@import url("../fonts/_notosans.css");

/* ═══════════════════════════════════════════════════════════════════════
   WISON NEW ENERGIES — 方向三 · 光・律   Light Cadence
   Round-3 visual language, built to the client note of 2026-08-11.

   The three colour laws it is written to (§三 of that note):
     white / off-white  →  the page itself. Most of every screen.
     blue               →  emphasis. Headings, one full-bleed block, footer.
     red                →  a precise accent. Never a field, never a slab.

   Everything below is organised by those laws, in that order.
   ═══════════════════════════════════════════════════════════════════════ */

:root{
  /* ── 1. NEUTRALS — the page ─────────────────────────────────────────
     Navy-tinted, never a flat grey, and --ink is deliberately NOT black:
     the client asked for 黑灰 rather than 最黑的黑. #16202E is 12.9:1 on
     white — well past AAA — while still reading as ink rather than soot. */
  --paper:      #FFFFFF;
  --paper-2:    #F4F7FA;   /* 白灰 — the alternating band            */
  --paper-3:    #E4EBF3;   /* hairlines, table rules                 */
  --paper-4:    #EAF1F8;   /* tinted panel inside a white section    */
  /* The 白灰 band, as a WASH rather than a solid. Composited over --paper
     it lands on #F4F7FA exactly (0.55·235 + 0.45·255 = 244, and the same
     for G and B), so the client's 白底/白灰底 alternation survives — but
     45% of the page field still reads through it. A solid --paper-2 would
     have blanked the backdrop on two of the five sections. */
  --wash:       rgba(235,241,246,.55);
  --ink:        #16202E;
  --ink-2:      #4A5A6E;
  --ink-3:      #7C8B9C;

  /* ── 2. BLUE — emphasis ─────────────────────────────────────────────
     --blue is the logo's own #1B365D. --blue-deep is the one full-bleed
     block; it is darker so white type sits on it at 14:1, and it is the
     ONLY large dark area on the page besides the footer. */
  --blue:       #1B365D;
  --blue-deep:  #102843;
  --blue-mid:   #2C5A8C;
  --blue-soft:  #EAF1F8;

  /* ── 3. RED — accent only ───────────────────────────────────────────
     --red is WISON RED from the manual, and it is the value every logo
     SVG in this project carries — so the loader stroke, the page
     accents and the header mark are literally one colour.
     --red-text is PANTONE 485C, the accessible one, for anything set at
     text size (4.86:1 on white). Never use --red for reading copy. */
  --red:        #FF0000;
  --red-text:   #DA291C;
  --red-deep:   #A4123F;
  --grad-red:   linear-gradient(100deg,#FF0000 0%,#DA291C 55%,#A4123F 100%);

  /* ── 4. THE MÖBIUS FAMILY ───────────────────────────────────────────
     Sampled directly off wison-divider.webp so every derived mark is the
     same light blue as the divider itself — the 清新、轻盈、渐变感 the
     client asked for, instead of another red shape. */
  --mob-1:      #78C0F0;
  --mob-2:      #A3D2FA;
  --mob-3:      #D8E8F8;
  --grad-mob:   linear-gradient(100deg,var(--mob-1),var(--mob-3));

  /* ── 5. GEOMETRY ────────────────────────────────────────────────────
     --seam-x is the single most important number in this file. The Möbius
     divider's crossing point — its one visual accent — sits at 49.4% of
     the artwork's width. Every folded section boundary on the page bends
     at that same x, and every fold carries a small red tick there. One
     vertical accent line runs the whole page. */
  --seam-x:     49.4%;
  --fold-h:     clamp(52px,6.6vw,104px);
  --seam-h:     clamp(54px,7vw,104px);   /* from separator-options.html   */
  /* --seam-over — how far the divider overflows its band, each way — is
     set per option further down, because it is a function of that option's
     aspect ratio. separator-options.html calls it 让位余量. This is the
     fallback for a page with no data-seam yet. */
  --seam-over:  calc(100vw / 7.36 - var(--seam-h) / 2);
  --rule:       1px solid var(--paper-3);

  /* ── 6. TYPE & RHYTHM ───────────────────────────────────────────────*/
  --sans: 'Noto Sans', system-ui, -apple-system, 'PingFang SC', sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  --wrap: 78rem;
  --gut:  clamp(1.25rem,4vw,3.5rem);
  --sect: clamp(4.5rem,8vw,7.5rem);
  --ease: cubic-bezier(.22,.61,.36,1);
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;font-family:var(--sans);color:var(--ink);background:var(--paper);
  font-size:clamp(.95rem,.9rem + .2vw,1.0625rem);line-height:1.62;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  /* `clip`, not `hidden`. overflow-x:hidden makes <body> a scroll
     container, and in WebKit a scroll container can become the containing
     block for its position:fixed descendants — which would make the page
     field scroll away with the document instead of staying pinned.
     overflow-x:clip does the same clipping without creating one. */
  overflow-x:clip}
img,video,svg{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4{margin:0;font-weight:600;letter-spacing:-.022em;line-height:1.1;
  color:var(--blue)}          /* 白底 → 蓝字, per §三.1 */
p{margin:0}
::selection{background:var(--mob-2);color:var(--blue-deep)}

.wrap{max-width:var(--wrap);margin-inline:auto;padding-inline:var(--gut)}
.section{padding-block:var(--sect);position:relative}
.num{font-family:var(--mono);font-feature-settings:"tnum" 1}

/* ═══ TYPE SCALE ══════════════════════════════════════════════════════ */
.h1{font-size:clamp(2rem,1.3rem + 3.4vw,4.15rem);line-height:1.04;
  letter-spacing:-.032em;font-weight:600}
.h2{font-size:clamp(1.7rem,1.15rem + 2vw,2.9rem);line-height:1.09;
  letter-spacing:-.028em}
.h3{font-size:clamp(1.1rem,.98rem + .55vw,1.4rem);letter-spacing:-.016em}
.lead{font-size:clamp(1rem,.95rem + .34vw,1.175rem);line-height:1.66;
  color:var(--ink-2);max-width:60ch}
.small{font-size:.8125rem;line-height:1.55;color:var(--ink-3)}

/* ═══ THE MÖBIUS GLYPH ════════════════════════════════════════════════
   Motif 3 of 5. The old eyebrow used a red right-triangle — a corner of
   the logo, i.e. exactly the 简单延展 the client pushed back on. This is
   the crossing itself: two strokes passing over each other, 10px wide,
   drawn in brand red at accent scale. Same idea as the divider, three
   orders of magnitude smaller. */
.eyebrow{display:inline-flex;align-items:center;gap:.6rem;
  font-size:.75rem;font-weight:600;letter-spacing:.17em;text-transform:uppercase;
  color:var(--blue-mid)}
/* the glyph keeps the mark's own 112:156 proportion — squashing it to a
   square would misdraw the logo at the one size nobody checks */
.eyebrow svg{width:.63rem;height:.88rem;flex:none;overflow:visible}
.eyebrow svg path{stroke:var(--red);stroke-width:1.4;fill:none;
  stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.on-dark .eyebrow{color:#9FC2E6}
.on-dark .eyebrow svg path{stroke:var(--mob-1)}

/* ═══ BUTTONS ═════════════════════════════════════════════════════════
   §三.2 asked for this by name: 可点击的按钮使用红渐变的 Hover 效果.
   At rest a button is blue or a hairline — no red at all. The red arrives
   only under the cursor, which is precisely "少量、高识别度的使用". */
.btn{display:inline-flex;align-items:center;gap:.6rem;position:relative;
  padding:.95rem 1.6rem;font-size:.875rem;font-weight:600;letter-spacing:.01em;
  border:1px solid transparent;isolation:isolate;overflow:hidden;
  transition:color .28s var(--ease),border-color .28s var(--ease)}
.btn::before{content:'';position:absolute;inset:0;z-index:-1;
  background:var(--grad-red);opacity:0;transform:translateX(-101%);
  transition:transform .42s var(--ease),opacity .2s}
.btn:hover::before{opacity:1;transform:translateX(0)}
.btn svg{width:1rem;height:1rem;transition:transform .3s var(--ease)}
.btn:hover svg{transform:translateX(4px)}

.btn--solid{background:var(--blue);color:#fff}
.btn--solid:hover{color:#fff;border-color:transparent}
.btn--line{border-color:var(--blue);color:var(--blue)}
.btn--line:hover{color:#fff;border-color:transparent}
.on-dark .btn--solid{background:#fff;color:var(--blue-deep)}
.on-dark .btn--solid:hover{color:#fff}
.on-dark .btn--line{border-color:rgba(255,255,255,.42);color:#fff}
.on-dark .btn--line:hover{border-color:transparent}

/* ═══ HEADER ══════════════════════════════════════════════════════════ */
.hdr{position:fixed;inset:0 0 auto;z-index:50;
  transition:background .35s var(--ease),box-shadow .35s var(--ease),
             border-color .35s var(--ease);
  border-bottom:1px solid transparent}
.hdr__in{display:flex;align-items:center;justify-content:space-between;
  gap:2rem;height:84px}
/* Sized against the previous build (wison.wbs-brands.com), which draws the
   lockup in a 95×52 box inside an 81px bar. Matching the BOX would have
   come up short: that PNG's artwork fills 86.9% of its own height, our SVG
   fills 90.3% of its viewBox, so like-for-like is visible ink, not box —
   52 × 0.869 = 45.2px of logo, which needs a 50px box here. */
.hdr__logo{height:50px;width:auto;transition:opacity .3s}
.hdr__logo--dark{display:none}
.hdr nav{display:flex;gap:clamp(1rem,2.1vw,2.1rem)}
.hdr nav a{font-size:.8125rem;font-weight:500;letter-spacing:.01em;
  color:rgba(255,255,255,.86);position:relative;padding-block:.4rem}
/* the nav underline is the page's smallest red accent */
.hdr nav a::after{content:'';position:absolute;left:0;right:100%;bottom:0;
  height:2px;background:var(--red);transition:right .32s var(--ease)}
.hdr nav a:hover::after{right:0}
.hdr--stuck{background:rgba(255,255,255,.94);backdrop-filter:blur(14px);
  border-bottom-color:var(--paper-3)}
.hdr--stuck .hdr__logo--light{display:none}
.hdr--stuck .hdr__logo--dark{display:block}
.hdr--stuck nav a{color:var(--ink-2)}
.hdr--stuck nav a:hover{color:var(--blue)}
@media(max-width:900px){.hdr nav{display:none}}

/* ═══ 1. HERO ═════════════════════════════════════════════════════════
   §二.1: 视频 Hero 作为核心视觉入口 … Hero 区域建议保持简洁，不需要叠加
   过多装饰元素. So: the video, the words, two buttons. Nothing else — the
   Gastech card that used to float here has moved down to §05.

   The bottom 26% fades to white. Two reasons, one of them structural: it
   gives the Möbius divider a LIGHT ground to sit on. Rule 03 of
   separator-options.html says the artwork only works on light backgrounds
   (ΔL≈51 on white vs ≈178 on dark, where the tails glare). This video's
   bottom band swings between luminance 45 and 147 across its eleven cuts,
   so it cannot be trusted — the scrim removes the variable entirely. */
.hero{position:relative;min-height:100svh;display:flex;align-items:center;
  background:var(--blue-deep);isolation:isolate;overflow:hidden}
.hero__media{position:absolute;inset:0;z-index:-2}
.hero__media video,.hero__media img{width:100%;height:100%;object-fit:cover}
/* Order matters. The vertical white-out must sit ABOVE the horizontal
   legibility wash — layered the other way round, the wash tints the white
   and leaves a grey band along the hero's bottom edge where it meets the
   seam, which is exactly the join the divider is meant to hide. */
.hero__scrim{position:absolute;inset:0;z-index:-1;
  background:
    linear-gradient(to bottom,rgba(9,22,38,.34) 0%,rgba(9,22,38,0) 26%,
      rgba(9,22,38,0) 56%,rgba(244,247,250,.55) 84%,var(--paper) 95%),
    linear-gradient(90deg,rgba(9,22,38,.74) 0%,rgba(9,22,38,.46) 46%,rgba(9,22,38,.10) 100%)}
.hero__in{width:100%;position:relative;z-index:1;
  padding-block:9rem calc(var(--seam-over) + 2.5rem)}
.hero__grid{display:grid;grid-template-columns:minmax(0,1fr) 25rem;
  gap:clamp(2rem,5vw,4.5rem);align-items:center}
@media(max-width:1100px){.hero__grid{grid-template-columns:minmax(0,1fr) 21rem}}
@media(max-width:900px){.hero__grid{grid-template-columns:1fr;
  gap:2.5rem;align-items:start}}
.hero__title{color:#fff;margin-top:1.15rem;
  font-size:clamp(2rem,1rem + 3vw,3.6rem);
  text-shadow:0 1px 30px rgba(6,16,28,.34)}
.hero__lead{color:rgba(255,255,255,.86);margin-top:1.5rem;max-width:46ch}
.hero__cta{display:flex;flex-wrap:wrap;gap:.85rem;margin-top:2.4rem}

/* the low-bandwidth still. §二.1 asked for it: 可能需要设置低流速下静帧位.
   v3.js drops the video and shows this when the connection reports
   save-data or 2g/3g. */
.hero[data-still] .hero__media video{display:none}
.hero__still{display:none}
.hero[data-still] .hero__still{display:block}

/* No scroll cue. One was drafted and cut: the divider below already reads
   as "continues downward", and a second device in the same 150px would be
   exactly the 叠加装饰元素 §二.1 asks us to keep out of the hero. */

/* ═══ 2. THE HERO → CONTENT DIVIDER ══════════════════════════════════
   The client's §二.2 in one element: the logo variant lifted OUT of the
   hero and set BELOW it, as the transition into the white content zone.

   Three options; <html data-seam> picks one. All three are in the markup
   and CSS shows the selected one, so switching costs one attribute.

   Implemented by the OVERLAY method, not the cropped one: the divider
   owns a short band of layout height and its artwork overflows it
   symmetrically, so nothing is cut. Neither the hero nor §01 may put
   overflow:hidden on an ancestor of this — .hero does clip, which is
   exactly why the seam is a SIBLING of it, not a child. */
.seam{position:relative;height:var(--seam-h);pointer-events:none;
  background:transparent}
.seam > *{display:none}

/* ── 1 · 光带 Ocean loop ─────────────────────────────────────────────
   The confirmed v4 artwork. Transparent PNG/WebP, 3.68:1. */
[data-seam="1"] .seam__rib[data-opt="1"]{display:block;
  position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);
  aspect-ratio:1402/381;
  background:url("../brand/wison-divider.webp") center/100% 100% no-repeat}
@media(min-resolution:2dppx){
  [data-seam="1"] .seam__rib[data-opt="1"]{
    background-image:url("../brand/wison-divider@2x.webp")}}

/* ── 2 · 水光 Caustic ────────────────────────────────────────────────
   Same Möbius topology, rendered as underwater refraction. 4.86:1.

   It is an OPAQUE image — it has no alpha channel — and drops its white
   through mix-blend-mode:multiply. That is not a shortcut: upstream
   measured a keyed-alpha version at 24.9 dB and visibly purple against
   43.5 dB for multiply, at five times the file size.

   Multiply means the ground underneath has to be light. It is: the hero's
   scrim reaches white before its bottom edge, and the page field below is
   near-white line work. On anything dark this option turns to mud. */
[data-seam="2"] .seam__rib[data-opt="2"]{display:block;
  position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);
  aspect-ratio:3168/652;
  background:url("../brand/wison-divider-caustic.webp") center/100% 100% no-repeat;
  mix-blend-mode:multiply;
  /* The artwork runs to its own top and bottom edges — those rows average
     252 but carry ink down to 123, so multiplied over the hero footage the
     cut edge reads as a hard horizontal line across the frame. Fading the
     last 14% each way dissolves it, and costs nothing: what is lost is the
     near-white extremity, which multiply was leaving untouched anyway. */
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 14%,
    #000 86%,transparent 100%);
  mask-image:linear-gradient(to bottom,transparent 0,#000 14%,
    #000 86%,transparent 100%)}
/* multiply needs a light ground (the upstream rule 03). This option
   overlaps the hero less than option 1 does, so the scrim can reach white
   sooner and the whole overlap sits on white. */
[data-seam="2"] .hero__scrim{
  background:
    linear-gradient(to bottom,rgba(9,22,38,.34) 0%,rgba(9,22,38,0) 26%,
      rgba(9,22,38,0) 52%,rgba(244,247,250,.55) 78%,var(--paper) 88%),
    linear-gradient(90deg,rgba(9,22,38,.74) 0%,rgba(9,22,38,.46) 46%,
      rgba(9,22,38,.10) 100%)}
@media(min-resolution:2dppx){
  [data-seam="2"] .seam__rib[data-opt="2"]{
    background-image:url("../brand/wison-divider-caustic@2x.webp")}}

/* ── 3 · 折角 Cut corner ─────────────────────────────────────────────
   No photograph. Two crossing chevrons: the footage is cut by a V, and a
   blue plane behind it is cut by a shallower ^. Blue shows only where the
   plane falls below the cut — which happens at the left and the right but
   not in the middle, so it arrives as two opposed wedges rather than a
   stripe. Geometry is measured off the client's reference, not eyeballed.

   The band carries NO layout height: a negative margin pulls it back over
   the hero's last --fb-h pixels, so §01 still begins at the hero's own
   bottom edge. That is what lets the transparent region above the cut show
   the footage — the band is an overlay on the hero, and the white it
   paints is what creates the cut in the first place. */
[data-seam="3"]{--fb-h:clamp(100px,10.39vw,210px);--seam-over:var(--fb-h)}
[data-seam="3"] .seam{height:var(--fb-h);margin-top:calc(var(--fb-h) * -1)}
[data-seam="3"] .seam__fold{display:block;position:absolute;inset:0;
  width:100%;height:100%}
.seam__blue{fill:#809ED1}          /* measured off the reference */
.seam__white{fill:var(--paper)}
.seam__cut{fill:none;stroke:rgba(16,40,67,.5);stroke-width:1;
  vector-effect:non-scaling-stroke}
/* the band already separates the hero from §01, so the section does not
   also need the overflow clearance the two image options ask for */
[data-seam="3"] .seam + .section{padding-top:var(--sect)}
/* This option needs the opposite of the other two. Options 1 and 2 are
   light artwork that has to land on a light ground, so the hero fades to
   white under them. Option 3 IS the transition — it cuts the footage — so
   the fade would only wash out the picture it is cutting. The horizontal
   legibility wash stays; the white-out goes. */
[data-seam="3"] .hero__scrim{
  background:
    linear-gradient(to bottom,rgba(9,22,38,.34) 0%,rgba(9,22,38,0) 30%,
      rgba(9,22,38,0) 100%),
    linear-gradient(90deg,rgba(9,22,38,.74) 0%,rgba(9,22,38,.46) 46%,
      rgba(9,22,38,.10) 100%)}

/* Clearance: how far the artwork overflows its band, each way, so nothing
   lands under it. It is a function of the option's aspect ratio, which is
   why it cannot be one constant — at 1440px option 1 needs 144px and
   option 2 only 96px, and option 3 needs none at all because it is drawn
   to fit. */
[data-seam="1"]{--seam-over:calc(100vw / 7.36 - var(--seam-h) / 2)}
[data-seam="2"]{--seam-over:calc(100vw / 9.72 - var(--seam-h) / 2)}

.seam + .section{padding-top:calc(var(--seam-over) + 1.25rem)}

/* ── the picker ──────────────────────────────────────────────────────
   A review control, and unlike round 2's animation picker it is meant to
   be seen: that one re-asked a question the client had answered, this one
   IS the question. It writes ?seam= into the URL so a choice can be sent
   on as a link. */
.seampick{position:fixed;right:1rem;bottom:1rem;z-index:60;display:flex;
  align-items:stretch;gap:1px;background:var(--paper-3);
  border:1px solid var(--paper-3);box-shadow:0 10px 30px rgba(9,22,38,.16);
  font-size:.75rem}
.seampick__l{display:flex;align-items:center;padding:.5rem .75rem;
  background:var(--blue-deep);color:#fff;font-weight:600;letter-spacing:.04em}
.seampick button{display:flex;flex-direction:column;gap:.1rem;
  padding:.45rem .8rem;background:var(--paper);border:0;font:inherit;
  color:var(--ink-2);cursor:pointer;text-align:left;transition:color .2s}
.seampick button b{font-size:.8125rem;font-weight:600;color:var(--blue)}
.seampick button span{font-size:.625rem;letter-spacing:.06em;color:var(--ink-3)}
.seampick button:hover{background:var(--blue-soft)}
.seampick button[aria-current=true]{background:var(--blue-soft)}
.seampick button[aria-current=true] b{color:var(--red-text)}
@media(max-width:700px){.seampick{left:1rem;right:1rem;justify-content:center}
  .seampick__l{display:none}}

/* ═══ 3. THE FOLD ═════════════════════════════════════════════════════
   Motif 2 of 5. §二.3 example line: 方向二（斜线的过渡改成折线的过渡）—
   the diagonal becomes a BENT line.

   Two segments, not one, and they run at the mark's own two angles: the
   left arm at the 29.2° family, the right at 36.7°, which is why the arms
   land at different heights instead of forming a symmetric V. The vertex
   is at --seam-x, the Möbius crossing — so on a long scroll every fold
   bends on the same vertical line the divider accents.

   .fold paints the colour ABOVE it; the band's own background is the
   colour BELOW. Set both with --above / --below.

   Drawn as SVG rather than clip-path so the tracing hairline can use
   vector-effect:non-scaling-stroke — the band is scaled non-uniformly
   (100 units across, 10 down, stretched to any viewport), and a CSS border
   or a second clipped polygon would come out as a wedge that thickens
   toward one end instead of a line. */
.fold{position:relative;height:var(--fold-h);line-height:0}
.fold svg{width:100%;height:100%;display:block}
.fold .fold__line{fill:none;stroke:var(--mob-1);stroke-width:1;opacity:.6;
  vector-effect:non-scaling-stroke}
/* the red tick at the vertex — the smallest deliberate red on the page */
.fold i{position:absolute;left:var(--seam-x);bottom:0;width:1px;height:11px;
  background:var(--red);transform:translateX(-.5px);opacity:.9}

/* ═══ 4. SECTION FURNITURE ════════════════════════════════════════════ */
.shead{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.9fr);
  gap:clamp(1.5rem,4vw,4rem);align-items:end;margin-bottom:clamp(2.5rem,4vw,3.75rem)}
@media(max-width:860px){.shead{grid-template-columns:1fr;align-items:start}}
.shead__n{font-family:var(--mono);font-size:.75rem;letter-spacing:.12em;
  color:var(--ink-3);margin-bottom:.9rem}
.shead h2{margin-top:.9rem}
.on-dark h2,.on-dark h3{color:#fff}
.on-dark .lead{color:rgba(255,255,255,.78)}
.on-dark .shead__n{color:rgba(255,255,255,.5)}

/* ═══ 5. EPCIC CHAIN — §01 ════════════════════════════════════════════ */
/* --chain-pad is pulled back out as a negative margin, so cell 01's TEXT
   still lines up with the section heading while the cell itself has the
   same internal padding as the other five. Without it the first cell's
   copy — and its hover tint, and the red hover bar — sat hard against the
   left edge, which the team flagged on 2026-08-14.

   The white ground is the second half of that note: the FLEET field drifts
   behind this section, and rigs crossing the EPCIC copy were interfering
   with it. The section is white too, so this reads as no box at all — the
   drawing simply passes behind the paper the table is set on. */
.chain{display:grid;grid-template-columns:repeat(6,1fr);
  /* capped at the gutter: at 390px the gutter is 20px, and pulling out a
     flat 1.35rem (21.6px) put the table 1.6px wider than the viewport on
     each side, which is enough to make the whole page scroll sideways */
  --chain-pad:min(1.35rem,var(--gut));
  margin-inline:calc(var(--chain-pad) * -1);
  border-top:var(--rule);counter-reset:step}
@media(max-width:1080px){.chain{grid-template-columns:repeat(3,1fr)}}
@media(max-width:680px){.chain{grid-template-columns:repeat(2,1fr)}}
.chain__i{padding:1.6rem var(--chain-pad) 1.9rem;border-right:var(--rule);
  position:relative;transition:background .3s}
.chain__i:last-child{border-right:0}
.chain__i::before{content:'';position:absolute;left:0;top:-1px;width:0;height:2px;
  background:var(--grad-red);transition:width .5s var(--ease)}
.chain__i:hover::before{width:100%}
.chain__i:hover{background:var(--paper-4)}
.chain__n{font-family:var(--mono);font-size:.6875rem;color:var(--mob-1);
  letter-spacing:.1em}
.chain__t{font-size:.9375rem;font-weight:600;color:var(--blue);margin:.55rem 0 .5rem}
.chain__d{font-size:.8125rem;line-height:1.56;color:var(--ink-2)}
@media(max-width:1080px){.chain__i:nth-child(3n){border-right:0}}
@media(max-width:680px){.chain__i:nth-child(3n){border-right:var(--rule)}
  .chain__i:nth-child(2n){border-right:0}}

/* ═══ 6. STATS ════════════════════════════════════════════════════════
   The one place a number is allowed a red mark: the unit suffix. Reading
   copy stays ink; the eye still gets a red anchor per figure. */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;
  background:var(--paper-3);border:var(--rule);margin-top:clamp(2.5rem,5vw,4rem)}
/* .stat cells are already opaque, so the grid only needs its 1px gaps
   filled to stop the field showing through between the figures */
@media(max-width:760px){.stats{grid-template-columns:repeat(2,1fr)}}
.stat{background:var(--paper);padding:1.75rem 1.5rem}
.on-dark .stats{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.16)}
.on-dark .stat{background:transparent}
.stat__v{font-size:clamp(1.9rem,1.3rem + 1.7vw,2.7rem);font-weight:600;
  font-variant-numeric:tabular-nums;
  color:var(--blue);letter-spacing:-.035em;line-height:1;display:flex;
  align-items:baseline;gap:.12em}
.on-dark .stat__v{color:#fff}
.stat__u{font-size:.5em;font-weight:600;color:var(--red-text);
  margin-left:.08em;letter-spacing:.01em}
.on-dark .stat__u{color:var(--mob-1)}
.stat__l{font-size:.75rem;letter-spacing:.06em;color:var(--ink-3);margin-top:.7rem}
.on-dark .stat__l{color:rgba(255,255,255,.6)}

/* ═══ 7. THE BLUE BLOCK — §02 ═════════════════════════════════════════
   The single 蓝色视觉区块 of the client's rhythm, and the replacement for
   the full-bleed RED slab of round 2 that §三.2 asked us to retire.

   It is the only large dark area on the page besides the footer — which
   is the other half of the note: 通过不同背景色及视觉元素的变化形成页面
   层次，而不是连续使用大面积深色块. */
.blue{background:var(--blue-deep);color:#fff;position:relative;
  isolation:isolate;overflow:hidden}
/* motif 5 of 5 — ONE oversized Möbius, drawn as line work at 7% opacity.
   A single instance placed off-axis, never a tiled pattern. */
.blue__mob{position:absolute;left:-1%;bottom:-7%;width:min(18rem,31%);
  z-index:-1;opacity:.17;pointer-events:none}
.blue__mob path{fill:none;stroke:var(--mob-1);stroke-width:1.4;
  stroke-linejoin:round;vector-effect:non-scaling-stroke}

.plat{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.08fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:start}
@media(max-width:940px){.plat{grid-template-columns:1fr}}
.plat__list{border-top:1px solid rgba(255,255,255,.17)}
.plat__b{display:grid;grid-template-columns:2.6rem 1fr auto;gap:1rem;
  align-items:center;width:100%;text-align:left;padding:1.15rem .25rem;
  background:none;border:0;border-bottom:1px solid rgba(255,255,255,.17);
  color:rgba(255,255,255,.62);font:inherit;cursor:pointer;position:relative;
  transition:color .3s var(--ease)}
.plat__b::before{content:'';position:absolute;left:0;bottom:-1px;width:0;height:1px;
  background:var(--grad-red);transition:width .45s var(--ease)}
.plat__b:hover{color:rgba(255,255,255,.9)}
.plat__b[aria-selected=true]{color:#fff}
.plat__b[aria-selected=true]::before{width:100%}
.plat__n{font-family:var(--mono);font-size:.6875rem;opacity:.55}
.plat__t{font-size:1.0625rem;font-weight:600;letter-spacing:-.01em}
.plat__b svg{width:1rem;height:1rem;opacity:0;transform:translateX(-6px);
  transition:opacity .3s,transform .3s var(--ease)}
.plat__b[aria-selected=true] svg{opacity:1;transform:none}

.plat__panel{display:none}
.plat__panel[data-on]{display:block;animation:fadeUp .5s var(--ease) both}
.plat__fig{position:relative;aspect-ratio:16/10;overflow:hidden;
  background:rgba(255,255,255,.06)}
.plat__fig img{width:100%;height:100%;object-fit:cover}
.plat__cap{display:flex;align-items:baseline;gap:.75rem;margin-top:1.4rem}
.plat__full{font-size:.75rem;letter-spacing:.13em;text-transform:uppercase;
  color:var(--mob-1)}
.plat__blurb{margin-top:.85rem;color:rgba(255,255,255,.8);max-width:52ch}
.plat__specs{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;
  background:rgba(255,255,255,.16);margin-top:1.75rem}
@media(max-width:560px){.plat__specs{grid-template-columns:1fr}}
.plat__spec{background:var(--blue-deep);padding:1.1rem 1.15rem}
.plat__spec b{display:block;font-size:1.15rem;font-weight:600;letter-spacing:-.02em}
.plat__spec span{display:block;font-size:.6875rem;letter-spacing:.08em;
  color:rgba(255,255,255,.55);margin-top:.45rem;text-transform:uppercase}

/* ═══ 8. LOCATION — §03 ═══════════════════════════════════════════════ */
.loc{display:grid;grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);
  gap:clamp(2rem,5vw,4rem);align-items:center}
@media(max-width:940px){.loc{grid-template-columns:1fr}}
.locmap{position:relative;overflow:hidden;background:var(--paper-3)}
.locmap img{width:100%;aspect-ratio:16/10;object-fit:cover}
.pin{position:absolute;transform:translate(-50%,-100%);
  display:flex;flex-direction:column;align-items:center;gap:.4rem}
.pin__l{background:rgba(255,255,255,.95);color:var(--blue);font-size:.6875rem;
  font-weight:600;letter-spacing:.02em;padding:.32rem .6rem;white-space:nowrap;
  box-shadow:0 2px 12px rgba(9,22,38,.22)}
.pin__d{width:9px;height:9px;background:var(--red);border-radius:50%;
  box-shadow:0 0 0 3px rgba(230,0,18,.28);position:relative}
.pin__d::after{content:'';position:absolute;inset:-3px;border-radius:50%;
  border:1px solid var(--red);animation:ping 2.6s var(--ease) infinite}
@keyframes ping{0%{transform:scale(.7);opacity:.85}
  70%,100%{transform:scale(2.6);opacity:0}}

.yards{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.25rem,2.6vw,2rem);
  margin-top:clamp(2.5rem,5vw,4rem)}
@media(max-width:760px){.yards{grid-template-columns:1fr}}
.yard{background:var(--paper);border:var(--rule);overflow:hidden;
  transition:border-color .35s var(--ease),transform .35s var(--ease)}
.yard:hover{border-color:var(--mob-1);transform:translateY(-3px)}
.yard__fig{aspect-ratio:16/9;overflow:hidden}
.yard__fig img{width:100%;height:100%;object-fit:cover;transition:transform .7s var(--ease)}
.yard:hover .yard__fig img{transform:scale(1.045)}
.yard__in{padding:1.5rem 1.6rem 1.75rem}
.yard__role{font-size:.8125rem;color:var(--ink-2);margin-top:.6rem;line-height:1.55}
.yard__rows{margin-top:1.35rem;border-top:var(--rule)}
.yard__row{display:flex;justify-content:space-between;gap:1rem;
  padding:.6rem 0;border-bottom:var(--rule);font-size:.8125rem}
.yard__row span{color:var(--ink-3)}
.yard__row b{font-weight:600;color:var(--blue);text-align:right}

/* ═══ 9. NETWORK — §04 ════════════════════════════════════════════════ */
.net{display:grid;grid-template-columns:minmax(0,.78fr) minmax(0,1.22fr);
  gap:clamp(2rem,5vw,4rem);align-items:center}
@media(max-width:940px){.net{grid-template-columns:1fr}}

/* ═══ 10. NEWS & EVENTS — §05 ═════════════════════════════════════════
   Where the Gastech card lives now that the hero is clean. It keeps the
   card's job — a dated, bookable thing — without putting a second focal
   point on top of the video. */
.evt{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.5fr);
  gap:clamp(1.5rem,4vw,3rem);align-items:stretch;margin-bottom:clamp(2rem,4vw,3rem)}
@media(max-width:940px){.evt{grid-template-columns:1fr}}
.evtcard{background:var(--blue);color:#fff;padding:clamp(1.6rem,3vw,2.2rem);
  display:flex;flex-direction:column;justify-content:space-between;
  position:relative;overflow:hidden}
.evtcard__tag{font-size:.6875rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--mob-1)}
.evtcard h3{color:#fff;margin:.9rem 0 .5rem;font-size:1.5rem}
.evtcard__when{font-size:.8125rem;color:rgba(255,255,255,.72)}
.evtcard__blurb{font-size:.875rem;color:rgba(255,255,255,.78);margin-top:.9rem;
  line-height:1.55}
.evtcard .btn{margin-top:1.6rem;align-self:flex-start}

.news{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1.25rem,2.6vw,2rem)}
@media(max-width:860px){.news{grid-template-columns:1fr}}
.ncard{background:var(--paper);border:var(--rule);overflow:hidden;
  display:flex;flex-direction:column;
  transition:border-color .35s var(--ease),transform .35s var(--ease)}
.ncard:hover{border-color:var(--mob-1);transform:translateY(-3px)}
.ncard__fig{aspect-ratio:16/10;overflow:hidden}
.ncard__fig img{width:100%;height:100%;object-fit:cover;transition:transform .7s var(--ease)}
.ncard:hover .ncard__fig img{transform:scale(1.045)}
.ncard__in{padding:1.3rem 1.4rem 1.6rem;display:flex;flex-direction:column;
  gap:.6rem;flex:1}
.ncard__k{font-size:.6875rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--red-text)}
.ncard__t{font-size:1rem;font-weight:600;color:var(--blue);line-height:1.32}
.ncard__d{font-size:.8125rem;color:var(--ink-2);line-height:1.55}

/* ═══ 11. FOOTER — the 蓝色底部栏 ═════════════════════════════════════ */
.foot{background:var(--blue-deep);color:#fff;padding-block:clamp(3.5rem,6vw,5rem) 2rem;
  position:relative;overflow:hidden}
.foot__grid{display:grid;grid-template-columns:minmax(0,1.15fr) repeat(3,minmax(0,1fr));
  gap:clamp(1.75rem,3.5vw,3rem)}
@media(max-width:940px){.foot__grid{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.foot__grid{grid-template-columns:1fr}}
.foot__logo{height:52px;width:auto;margin-bottom:1.25rem}
.foot__addr{font-size:.8125rem;line-height:1.7;color:rgba(255,255,255,.62);
  max-width:34ch}
.foot h4{font-size:.75rem;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(255,255,255,.5);font-weight:600;margin-bottom:1rem}
.foot ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.6rem}
.foot li a{font-size:.8125rem;color:rgba(255,255,255,.78);transition:color .25s}
.foot li a:hover{color:var(--mob-1)}
.foot__bar{margin-top:clamp(2.5rem,5vw,3.5rem);padding-top:1.5rem;
  border-top:1px solid rgba(255,255,255,.14);display:flex;flex-wrap:wrap;gap:1rem;
  justify-content:space-between;font-size:.75rem;color:rgba(255,255,255,.45)}

/* ═══ 14. THE PAGE FIELD ══════════════════════════════════════════════
   Round 2's mark field, variant 3 · 队 FLEET — Wison's own assets (FLNG,
   FSRU, rig, turbines, jacket, module rack, from the ESG report elements)
   drifting as fine line-work on the mark's own 29.2° bearing.

   FIXED, not scrolled. One instance for the whole document, pinned to the
   viewport: the page travels over it and it stays where it is. That is the
   behaviour the client pointed at on kaseware.com, and it is why the field
   no longer collides with anything — a backdrop that holds still reads as
   depth, whereas two per-section instances scrolling under the copy read
   as interference, which is what the earlier white plate was patching.

   What covers it is now a deliberate list: the video hero, the blue block,
   the seascape band and the footer are opaque, so the field is simply not
   there. Everything else is clear or washed.

   Palette is the one change from round 2, which ran a neutral blue-grey:
   these two values put the fleet inside this direction's Möbius family. */
.pagefield{position:fixed;inset:0;z-index:0;pointer-events:none;
  --mf-line:#B6CDE4;--mf-soft:#D8E7F4}
.markfield{overflow:hidden}
.markfield canvas{display:block;width:100%;height:100%}

/* Everything authored stacks above the backdrop. The seam sits higher
   still: its artwork overflows upward over the hero, which is itself
   painted above the field. */
.hero,.section,.foot{position:relative;z-index:1}
.fold{z-index:2}
.seam{z-index:4}

/* the two grounds a light section can have */
.sect--clear{background:transparent}
.sect--wash{background:var(--wash)}

/* ═══ 15. THE SEASCAPE BAND ═══════════════════════════════════════════
   The loading screen's own backdrop, reused as the ground for §04. It
   closes a loop — the image the visitor waits on returns as the place the
   global network is described — and it is the bright, high-key ocean the
   client asked for in §二.4, not the navy-black one they rejected.

   Scrimmed white top and bottom for two reasons: the fold above has to
   arrive on white to read at all, and the stats grid at the foot of the
   section would otherwise sit on the dark water. What survives is the
   horizon and its light, across the middle third. */
.sea{position:relative;isolation:isolate;background:var(--paper)}
.sea::before{content:'';position:absolute;inset:0;z-index:-1;
  background:url("../img/loader-sea.jpg") center 72%/cover no-repeat}
.sea::after{content:'';position:absolute;inset:0;z-index:-1;
  background:linear-gradient(to bottom,
    var(--paper) 0%,rgba(255,255,255,.40) 15%,rgba(255,255,255,.16) 45%,
    rgba(255,255,255,.52) 82%,var(--paper) 100%)}
.sea > .wrap{position:relative;z-index:1}

/* ═══ 16. THE CAMPAIGN CARD ═══════════════════════════════════════════
   The reference build's HeroCampaignCard, back in the hero at the client's
   request. Structure, copy and behaviour are carried over as-is; the skin
   is the one thing that changes.

   The reference is a dark frosted panel with cyan accents — round 1's
   vocabulary. Here it is a LIGHT panel: 白底蓝字 per §三.1, square corners
   rather than the 1.6rem radius, and the active tab marked with the same
   red underline the nav and the platform list already use. On a dark video
   it also balances the white headline opposite it, and previews the white
   page below.

   The forms are front-end only, exactly as in the reference. §六 of the
   client note specifies the real flow (审核 → 时段锁定 → 两封邮件); this is
   the front end it would eventually be wired to. */
.ecard{background:rgba(255,255,255,.94);backdrop-filter:blur(16px);
  box-shadow:0 24px 70px rgba(6,16,28,.30);color:var(--ink);
  align-self:center;overflow:hidden}
/* The card is a LIGHT island inside .hero.on-dark, so every reversed rule
   that scope sets has to be handed back explicitly — otherwise the event
   title is white on white and the primary button is a white block on a
   white card. Same specificity as the .on-dark rules, declared later. */
.ecard h2,.ecard h3{color:var(--blue)}
.ecard .btn--solid{background:var(--blue);color:#fff}
.ecard .btn--solid:hover{color:#fff}
@media(max-width:900px){.ecard{max-width:26rem}}

.ecard__tabs{display:grid;grid-template-columns:repeat(3,1fr);
  border-bottom:var(--rule)}
.ecard__tab{position:relative;padding:.95rem .5rem;background:none;border:0;
  font:inherit;font-size:.8125rem;font-weight:600;color:var(--ink-3);
  cursor:pointer;transition:color .25s}
.ecard__tab:hover{color:var(--blue)}
.ecard__tab[aria-selected=true]{color:var(--blue)}
.ecard__tab::after{content:'';position:absolute;left:.9rem;right:.9rem;
  bottom:-1px;height:2px;background:var(--red);transform:scaleX(0);
  transition:transform .32s var(--ease)}
.ecard__tab[aria-selected=true]::after{transform:scaleX(1)}

.ecard__panel{display:none;padding:1.5rem}
.ecard__panel[data-on]{display:block;animation:fadeUp .38s var(--ease) both}

.ecard__top{display:flex;align-items:center;justify-content:space-between;
  gap:1rem}
.ecard__eyebrow{font-size:.6875rem;font-weight:600;letter-spacing:.18em;
  text-transform:uppercase;color:var(--ink-3)}
.ecard__badge{font-size:.6875rem;font-weight:600;letter-spacing:.04em;
  color:var(--blue);background:var(--blue-soft);padding:.25rem .6rem}
.ecard__name{font-size:1.6rem;margin-top:.75rem;letter-spacing:-.025em}
.ecard__meta{display:flex;align-items:center;gap:.6rem;margin-top:.7rem;
  font-size:.8125rem;color:var(--ink-2)}
.ecard__meta svg{width:1rem;height:1rem;flex:none;color:var(--blue-mid)}
.ecard__body{margin-top:1rem;font-size:.8125rem;line-height:1.6;
  color:var(--ink-2)}

/* the 2025 recap opener */
.ecard__recap{display:flex;align-items:center;gap:.8rem;width:100%;
  margin-top:1.1rem;padding:.5rem;background:var(--paper-2);
  border:var(--rule);cursor:pointer;text-align:left;font:inherit;
  transition:border-color .3s var(--ease),background .3s}
.ecard__recap:hover{border-color:var(--mob-1);background:var(--blue-soft)}
.ecard__thumb{position:relative;width:5rem;height:3rem;flex:none;
  overflow:hidden}
.ecard__thumb img{width:100%;height:100%;object-fit:cover}
.ecard__play{position:absolute;inset:0;display:grid;place-items:center;
  color:#fff;background:rgba(6,16,28,.22);transition:background .3s}
.ecard__play svg{width:1.15rem;height:1.15rem;
  filter:drop-shadow(0 1px 3px rgba(0,0,0,.55))}
.ecard__recap:hover .ecard__play{background:rgba(6,16,28,.04)}
.ecard__recaptxt b{display:block;font-size:.8125rem;font-weight:600;
  color:var(--blue)}
.ecard__recaptxt i{display:block;font-size:.6875rem;font-style:normal;
  color:var(--ink-3);margin-top:.15rem}
.ecard__cta,.ecard__submit{width:100%;justify-content:center;margin-top:1.15rem}

/* the two forms */
.ecard__h{font-size:1.2rem}
.ecard__note{margin-top:.45rem;font-size:.8125rem;line-height:1.6;
  color:var(--ink-2)}
.ecard__form{display:flex;flex-direction:column;gap:.6rem;margin-top:1.15rem}
/* an explicit `display` outranks the UA's [hidden]{display:none}, so the
   form stayed on screen underneath its own success panel. Scoped rather
   than a global !important: .ldr[hidden] deliberately keeps display:grid
   so its fade-out can run. */
.ecard__form[hidden]{display:none}
.ecard__f{width:100%;padding:.7rem .85rem;font:inherit;font-size:.875rem;
  color:var(--ink);background:var(--paper);border:var(--rule);
  border-radius:0;outline:none;resize:none;
  transition:border-color .25s,box-shadow .25s}
.ecard__f::placeholder{color:var(--ink-3)}
.ecard__f:focus{border-color:var(--blue-mid);
  box-shadow:0 0 0 3px rgba(44,90,140,.14)}
.ecard__submit{margin-top:.35rem}
.ecard__priv{font-size:.6875rem;line-height:1.5;color:var(--ink-3)}

.ecard__ok{margin-top:1.4rem;padding:1.5rem 1.25rem;text-align:center;
  background:var(--blue-soft);border:1px solid var(--mob-2);
  animation:fadeUp .4s var(--ease) both}
.ecard__ok p{font-size:.875rem;line-height:1.6;color:var(--ink-2);
  margin-top:.9rem}
.ecard__tick{display:grid;place-items:center;width:2.6rem;height:2.6rem;
  margin-inline:auto;border-radius:50%;background:var(--paper);
  color:var(--blue)}
.ecard__tick svg{width:1.3rem;height:1.3rem;stroke-width:2.2}
.ecard__again{margin-top:.9rem;background:none;border:0;font:inherit;
  font-size:.6875rem;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--red-text);cursor:pointer}
.ecard__again:hover{color:var(--blue)}

/* the recap popup. Lives at the end of <body>, NOT inside .hero: the hero
   clips its overflow, which would trap a fixed overlay inside it. */
.recap{position:fixed;inset:0;z-index:120;display:grid;place-items:center;
  padding:1rem;background:rgba(6,16,28,.82);backdrop-filter:blur(4px)}
.recap[hidden]{display:none}
.recap__box{width:min(92vw,46rem);background:var(--blue-deep);
  box-shadow:0 40px 120px rgba(0,0,0,.55)}
.recap__bar{display:flex;align-items:center;justify-content:space-between;
  gap:1rem;padding:.85rem 1.15rem;border-bottom:1px solid rgba(255,255,255,.14)}
.recap__bar p{font-size:.875rem;font-weight:600;color:#fff}
.recap__x{background:none;border:0;padding:.2rem;color:rgba(255,255,255,.6);
  cursor:pointer;transition:color .25s}
.recap__x:hover{color:#fff}
.recap__x svg{width:1.25rem;height:1.25rem}
.recap video{width:100%;aspect-ratio:16/9;background:#000;display:block}

/* ═══ 12. REVEAL ══════════════════════════════════════════════════════ */
.reveal{opacity:0;transform:translateY(18px);
  transition:opacity .75s var(--ease),transform .75s var(--ease)}
.reveal.in{opacity:1;transform:none}
@keyframes fadeUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}

/* ═══ 13. LOADER ══════════════════════════════════════════════════════
   Motif 4 of 5. The mark is one closed, self-intersecting path — four
   vertices, crossing itself once — so the "Möbius" the client sees in the
   logo is geometrically real and the whole thing can be drawn in a single
   stroke. The pen traces it; the artwork underneath is the untouched
   vector, revealed through a mask, so the final frame is the exact logo
   and cannot drift.

   Backdrop is the bright seascape the client pointed at in §二.4 —
   explicitly NOT the navy-black ocean they rejected. */
.ldr{position:fixed;inset:0;z-index:200;display:grid;place-items:center;
  background:#dfe7ef url("../img/loader-sea.jpg") center/cover no-repeat;
  transition:opacity .7s var(--ease),visibility .7s}
.ldr[hidden]{opacity:0;visibility:hidden;display:grid}
/* 42rem, not 30. The lockup was rendering at 480px on a 1440 screen, which
   is small for a full-screen moment and — the reason it changed — put the
   sparks at barely a pixel across. Everything inside scales with it. */
.ldr__in{width:min(42rem,80vw);text-align:center;
  display:flex;flex-direction:column;align-items:center}
/* Scoped to the lockup by id. A bare `.ldr svg` also caught the arrow
   inside the enter button and blew it up to the full column width. */
#ldrLogo{width:100%;height:auto;overflow:visible}
.ldr__tag{margin-top:1.5rem;font-size:.6875rem;letter-spacing:.22em;
  text-transform:uppercase;color:var(--blue-mid);opacity:0}
/* No progress bar. It was measuring the animation, not the page — a
   4.9s bar that always fills at the same rate tells the visitor nothing,
   and it competed with the one line the pen is drawing. The screen now
   simply holds on the finished lockup.

   REVIEW BUILD: it waits for this button instead of dismissing itself, and
   it plays on every visit. See the two PRODUCTION notes in v3.js. */
.ldr__go{margin-top:1.75rem;opacity:0;transform:translateY(6px);
  pointer-events:none;
  transition:opacity .6s var(--ease) .15s,transform .6s var(--ease) .15s}
.ldr[data-done] .ldr__go{opacity:1;transform:none;pointer-events:auto}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;
    animation-iteration-count:1!important;transition-duration:.01ms!important}
  .reveal{opacity:1;transform:none}
  html{scroll-behavior:auto}
}
