/* ══════════════════════════════════════════════════════════════════════════
   #about — THE ANATOMICAL PLATE

   Every selector is scoped to #about on purpose: the plate reuses short names
   (.stage, .ring, .link, .name, .u, .w) that the rest of the page is free to
   claim later, and its palette overrides --dim and --line, which are site-wide
   tokens. Behaviour lives in about-plate.js.

   THIS FILE IS LOADED BY BOTH index.html AND lab/about-plate.html. It used to
   live inline in index.html, with the lab keeping its own copy — and by
   2026-08-07 the two had drifted far enough apart that the lab was showing a
   different section: 5vw block insets that production had dropped, --dim at
   #5c5c5c against production's #8a8a8a, no legibility halo at all. Tuning a
   value in the lab and porting it is only meaningful if the lab is the same
   thing, so there is one copy now and no port step.

   The lab adds a harness on top — device frame, beat scrub, per-beat dials, a
   ghost of the floating CTA — and adds nothing to the plate itself.
   ══════════════════════════════════════════════════════════════════════════ */
#about{
  /* The plate's own palette. Scoped, NOT global: --dim and --line here differ
     from site.css on purpose (the plate needs a brighter dim and a heavier
     hairline against the dither field), and letting those leak would have
     restyled every seam on the page. --text-2 and the easings are additions. */
  /* --dim was #5c5c5c, which is 3.0:1 on this background — and every single
     thing it colours here is the SMALLEST type on the page: the 9.5px mono
     micro-labels (BRAND IDENTITY, PRODUCTION APPS, the stack list). Measured on
     a real handset they were the one class of text that genuinely could not be
     read, on every beat, and they are sitting over a dither field and the
     ambient blob as well as the background. 5.8:1 now, which is AA at that
     size. It lands on the same value as --muted on purpose: the micro-labels
     do not need colour to say they are subordinate, because 9.5px uppercase
     mono against 12.5px sentence case already says it twice. */
  --text-2:#c4c4c4;--dim:#8a8a8a;
  /* THE HAIRLINES ARE LIME-GREY NOW (#65), not white at .13. The .figs lattice
     at that value was nearly invisible on a real handset — it is in every
     screenshot from #57 and it read as a white line that had failed rather
     than as a rule that was meant to be quiet. --accent-line is both a little
     stronger and of the accent, so the lattice reads as drafting on a plate
     made of the same stuff as the section. It is not text, so it has no
     contrast minimum; what it has to survive is the dither field and the blob
     behind it, which is what the white lost to. */
  --line:var(--accent-line);
  /* Emil's curves — the built-ins are too weak to read as intentional. */
  --ease-out:cubic-bezier(0.23,1,0.32,1);
  --ease-in-out:cubic-bezier(0.77,0,0.175,1);
  /* The plate is a full-bleed pinned stage and owns its own insets. */
  padding:0;
  /* SOLID AGAIN, and the blob behind it is stopped rather than merely hidden —
     about-plate.js drives --blob to 0 across this section and puts .blob-off on
     the root, which makes home.js's loop return before it steps 6000 particles
     and issues a draw call nobody can see. His call: "do something about the
     blob behind it, to pause/hide it (make it cheaper for the device to run the
     dithered head), and bring back the solid bg".
     The wireframe crossing the plate was the original reason this was opaque;
     it is the right answer again for a different reason. */
  background:var(--bg);

  /* THE FIELD'S OWN INK (#65). The grain and the head were the same white
     because they were the same uniform. This is the first place a lime-grey
     earns its place: a neutral field reads as noise, a field of the accent
     reads as the plate being made of the same stuff the section is.
     Desaturated hard — at 0.17 alpha over near-black it only has to tint, and
     anything with real chroma turns the whole plate green. */
  --grain-ink:#9fae86;
}
/* The site's .s-label carries the section-progress rule in ::before; the plate
   inherits it rather than redefining a plainer one. Only the 64px gap has to
   go — this section's budget is one viewport. */
/* position:relative so they paint above the full-bleed dither field, which is
   now an earlier, absolutely-positioned sibling. */
#about .s-label{margin-bottom:0;position:relative}
#about .phead{position:relative}

/* The accent voice, lifted verbatim from site.css so the plate cannot drift
   from the rest of the site. Every lime italic on this page is this rule. */
#about .ac{font-family:var(--fs);font-style:italic;font-weight:400;color:var(--accent);
  letter-spacing:0}
#about a:focus-visible,#about [tabindex]:focus-visible{outline:2px solid var(--accent);
  outline-offset:3px;border-radius:1px}

/* Pinned scrub, the same shape #how uses: the section holds the viewport while
   the page scrolls past it, and that travel is the choreography's timeline.
   Nothing scrolls INSIDE the section — it still has to hold itself in view. */
/* 520vh. Longer again, because the reveal itself is now longer per line and the
   quote leads before 01. 560 was only ever too long when the reveals were
   instant — with a real cascade there is something happening the whole way. */
/* No height. The pin is a ScrollTrigger now (see about-plate.js) and its
   pinSpacing creates the scroll length — leaving 520vh here as well would make
   the section pay for the same travel twice. */
#about .pin{position:relative}

/* The section owns the viewport and never scrolls inside itself. */
/* Full bleed, his call. The 1560px cap left a gutter either side on a wide
   screen, and the plate is a specimen field rather than a text column — it
   should own the glass. The ring's own minmax() columns still stop the copy
   from stretching into unreadable measures. */
/* position:relative, not sticky — ScrollTrigger owns the pinning now. */
#about .plate{position:relative;height:100vh;max-width:none;margin:0;
  /* Top padding clears the nav, which the lab page did not have. #main-nav is
     fixed at top:16 and 57 tall, so it owns y 0..73 — and it spans the label
     outright below 860px, where it goes full width. Every other section clears
     it with .section's 110px; the plate had that padding removed because it is
     a full-bleed pinned stage, so it has to buy the clearance here.
     The cost comes out of .stage (flex:1), which makes the head slightly
     smaller — fit() re-solves the camera distance from whatever is left, so
     nothing needs re-tuning by hand. */
  /* One variable, two uses: the copy is inset by it and the dither field is
     bled back out by exactly the same amount (see #about-head-layer). */
  /* The gutter is the page's, not the plate's — see :root{--gutter}. It used
     to be clamp(24px,3vw,56px), which put #about's label 4px right of every
     other section at 1920 and a different amount wrong at every other width. */
  /* --pad-t STAYS at --head-top. Those 85px on a phone are nav clearance, not
     spare room: the pill owns y 16..73, and cutting 20px off put the label at
     65 — inside the pill. It read fine until the nav came back on scroll-up and
     landed on top of it.

     Which also settles the "make the About label follow the others" request:
     it cannot rise while the pill is there, and it cannot rise only when the
     pill is gone either, because --pad-t is PADDING. Toggling padding reflows
     the document and changes its height mid-scroll — the instability this page
     has just been dug out of. #about is a third implementation of --head-top,
     after the sticky top the other labels use and the pin padding #how uses,
     and that is the thing to fix properly rather than paper over.

     The height he actually wanted comes from the GAP instead, which owes
     nothing to the nav: it lifts the headline and the canvas without moving the
     label a pixel. Tightened from 1.8vh to 1.1vh, which is where the copy on
     ONE MAN AGENCY was ending up under the CTA float. */
  /* --about-head-top exists only below 860, where it is 85. Above that it is
     unset and this falls through to --head-top, so #about rests on the same
     line as every other label on a desktop. See the note in the 860 query. */
  --pad-x:var(--gutter);--pad-t:var(--about-head-top,var(--head-top));--pad-b:52px;
  padding:var(--pad-t) var(--pad-x) var(--pad-b);
  display:flex;flex-direction:column;gap:clamp(8px,1.1vh,16px)}
#about .phead{display:flex;align-items:flex-end;gap:clamp(24px,4vw,64px);flex-wrap:wrap}
/* THE SAME EXPRESSION AS .how-h, not a number that happens to match today
   (#56 — "the label and headline should match positions and sizes of #how").
   It was clamp(30px,3.6vw,50px) and carried no --k, so it also stopped growing
   at 4K while #how kept going. Case and line-height stay the section's own:
   he asked for position and size, and #how is uppercase where this is not. */
#about .plate-h{font-size:calc(clamp(34px,4.6vw,56px) * var(--k));font-weight:900;line-height:.98;
  letter-spacing:-.022em;margin:0;max-width:13ch}
#about .plate-h em{font-family:var(--fs);font-style:italic;font-weight:400;
  color:var(--accent);letter-spacing:0}
/* The quote voice. One rule, two homes: it replaced the Stack title in 05, and
   it carries the merged process line under his name in 01. Making them the same
   object is the point — the plate says two things in the same register, one at
   the top of the ring and one at its left. */
/* .ann p is (0,0,1,1) and .qline was (0,0,1,0), so the annotation's body rule
   was silently winning and clamping this to 14.4px. Qualifying it fixes the
   cascade rather than reaching for !important. */
#about .ann p.qline,#about .qline{color:var(--text-2);font-size:clamp(16px,1.72vw,25px);
  line-height:1.3;letter-spacing:-.014em;margin:0 0 10px;text-wrap:balance}
#about .qline .ac{font-size:1.06em}
/* The left one carries more words, so it holds a narrower measure at a slightly
   smaller size — same voice, same weight of statement, still clearly the pair
   of the one at the top of the ring. */
/* No 26ch cap. The measure was narrower than the figures table directly below
   it, so the paragraph wrapped somewhere around the table's middle column and
   the two stopped reading as one block. It now runs the block's full width and
   the table sets the measure. */
#about .ann p.qline-l{font-size:clamp(14px,1.36vw,19px);max-width:none;text-wrap:pretty}

/* ---- the ring ----
   Three columns, three rows, and a hole in the middle. The canvas is a layer
   BEHIND all of it at full stage height, so the head is sized by the section
   rather than by whatever row it was sharing. */
/* pointer-events:none is load-bearing since the canvas moved out of here. The
   dither layer is now an earlier sibling BEHIND the stage, so the stage — a
   positioned, full-size box — was swallowing every pointermove before it could
   reach the canvas, and no face region was hoverable at all. The ring already
   worked this way; the stage has to as well, and .ann re-enables itself. */
#about .stage{position:relative;flex:1;min-height:0;pointer-events:none}
/* Bled out past the plate's padding on all four sides, so the dither field runs
   the full width AND height of the section — behind the label and headline too.
   The copy stays inset; only the FIELD is full bleed, which is the point: it is
   the ground the plate is drawn on, and a ground with a gutter reads as a card.

   z-index 0, not 1. It is the first child of .plate now, so every positioned
   sibling after it paints on top without needing a stack of its own. At 1 it
   covered the headline.

   Bleeding it does NOT resize the head: fit() still solves the head against the
   RING's height and then converts that to a fraction of this larger canvas, so
   the extra area is room to move rather than a bigger subject. */
/* inset:0, not negative offsets. An absolutely positioned child is laid out
   against its ancestor's PADDING box, and .plate is that ancestor now — so
   inset:0 already spans the whole section including the padding. The negative
   offsets this replaces were written when the layer lived inside .stage, whose
   box starts inside the padding; kept there they overshot by the padding twice. */
#about-head-layer{position:absolute;inset:0;
  display:flex;align-items:center;
  justify-content:center;z-index:0}
#about-gl{display:block;cursor:crosshair}
#about-overlay{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;
  overflow:visible;z-index:2}
/* z-index is load-bearing: #about-overlay is an earlier sibling than nothing here,
   but the canvas layer would still paint over a leader without it, which reads
   exactly like a leader that is too short. */
/* crispEdges was making every diagonal a staircase, which is most of why they
   read as a sketch — a drafted leader is a clean hairline at any angle. Round
   caps and joins finish the elbow instead of leaving a square corner. */
#about-overlay .lead{stroke:rgba(255,255,255,.26);stroke-width:1;fill:none;
  stroke-linecap:round;stroke-linejoin:round;
  transition:stroke .25s}
#about-overlay .lead.hot{stroke:rgba(184,255,0,.55)}
/* The terminal tick. A real plate ends its leader on a short perpendicular
   serif at the feature, not a dot and not a bare stop. */
#about-overlay .tick{stroke:rgba(255,255,255,.42);stroke-width:1;stroke-linecap:round}
#about-overlay .tick.hot{stroke:var(--accent)}
/* No anchor dots. They were a debug affordance, and sitting one on each pupil
   pointed straight at eye alignment nobody would otherwise look for. */
#about-overlay .cell{fill:var(--text);shape-rendering:crispEdges}
/* The brace carries 01 on its own, without a leader, so it has to hold its own
   against the grain now behind it — at --line it disappeared into the field. */
#about-overlay .brace{stroke:rgba(255,255,255,.30);stroke-width:1.2;fill:none;
  stroke-linecap:round}

#about .ring{position:relative;z-index:3;height:100%;display:grid;
  grid-template-columns:minmax(190px,1fr) minmax(300px,.95fr) minmax(190px,1fr);
  grid-template-rows:auto 1fr auto;
  grid-template-areas:
    "core  crown  creative"
    "bio   .      noctvm"
    ".     jaw    .";
  column-gap:clamp(20px,3vw,52px);
  pointer-events:none;                 /* the head keeps the mouse */
}
#about .ann{pointer-events:auto;
  /* The copy is the ONE thing on this plate that is not decoration, and it is
     read against three moving layers at once: the head's own 2px dither, the
     dot field the whole plate is made of, and the ambient blob showing through
     (--blob holds at 0.18 here, which is dim, not absent). Colour alone cannot
     win that — a glyph and the grain behind it can be the same value.
     One tight halo, so each letter carries its own separation wherever it
     happens to land. 4px of blur rather than a wide scrim: the words repaint
     every few frames while a beat is scrubbing, and a large blur radius is the
     part of text-shadow that costs. It inherits to every word span, so the
     halo arrives masked with its own word rather than ahead of it. */
  text-shadow:0 1px 4px rgba(0,0,0,.92)}
/* One system across the whole plate: a display value carrying the read, and a
   mono micro-label naming it. The figures block already did this (38px against
   9px) and it is the best-looking thing here, so the annotations now match it.
   Heading against label is ~3:1, which is as far as the one-viewport rule will
   allow — the 10:1 the rubric wants needs vertical room this section cannot
   spend. The figures carry the gasp instead. */
#about .ann h3{font-size:clamp(20px,1.95vw,28px);font-weight:900;letter-spacing:-.022em;
  line-height:1;margin:0 0 12px}
#about .ann .name{font-size:clamp(24px,2.35vw,34px);font-weight:900;letter-spacing:-.028em;
  line-height:1;margin:0 0 11px}
#about .ann p{margin:0;font-size:clamp(12.5px,1vw,14.5px);line-height:1.55;color:var(--muted)}
#about .ann .lines{list-style:none;margin:0;padding:0}
#about .ann .lines li{font-size:clamp(12.5px,1.02vw,14.5px);line-height:1.45;
  color:var(--text-2);margin-bottom:13px}
/* The discipline becomes the label and the PROOF becomes the read, which is
   also the right way round: the evidence is what convinces, not the noun. */
#about .ann .lines b{display:block;font-family:var(--fm);font-size:9.5px;font-weight:500;
  letter-spacing:.15em;text-transform:uppercase;color:var(--dim);margin-bottom:4px}

/* Every reveal unit is masked independently, so a block assembles line by line
   rather than all at once. will-change is deliberate: the mask changes every
   few frames during a beat and promoting the layer keeps it off the paint path. */
#about .u{will-change:mask-image,opacity}

/* ---- hover: type turns to the accent voice ----
   Individually addressable, as he asked: the heading on its own, and each list
   item on its own. The font swap changes metrics, so only elements that are
   left- or right-aligned within their own column get it — a centred one would
   visibly jump. */
#about .ann h3,#about .ann .name,#about .ann .lines li,#about .figs .f,#about .figs .v,#about .ac,#about .hv{
  transition:color .2s, transform .3s cubic-bezier(.16,1,.3,1)}
/* .hv is opt-in — only Core, Creative and the word "building". One-man agency
   does not take it: its emphasis is already "agency", and swapping a CENTRED
   heading would shift it sideways every time the pointer crossed it.
   Triggered by the whole card, not the word: the word is a small target, and
   the card is the thing the reader is actually addressing. */
/* Pressables confirm they heard you. 160ms is the press-feedback band. */
#about .cv,#about .link{display:inline-block;transition:transform .16s var(--ease-out),color .18s}
#about .cv:active,#about .link:active{transform:scale(.97)}

/* Reduced motion: keep the colour, drop the movement. Fewer and gentler, not
   none — the lift carries no information the colour does not. */

/* ---- per-item lift ----
   Each entry is its own object: label and proof lift together as one pair,
   because they are one fact. Gated behind a real pointer — on touch, hover
   fires on tap and leaves items stuck in the lifted state. */
#about .ann .lines li,#about .figs .f{transition:transform .19s var(--ease-out),color .18s}
/* --arrive is 1 while a unit is still coming in and 0 once it has settled, so
   each line LANDS lit and cools to its resting colour. That is the hover
   affordance expressed as a scroll event: on touch there is no hover to give,
   and on desktop it runs alongside it. */
/* The scroll-driven green: each line ARRIVES lit and cools to its reading
   colour. This is back, and the earlier "everything is green" was never this
   rule — it was --arrive, which used to read 1 before a line existed as well as
   during it. It is a pulse now (see about-plate.js), so a line is only accent
   while it is actually landing. */
#about .ann .lines li{color:color-mix(in srgb,var(--accent) calc(var(--arrive,0)*90%),var(--text-2))}
#about .ann .lines li b{color:color-mix(in srgb,var(--accent) calc(var(--arrive,0)*80%),var(--dim))}
#about .figs .v{color:color-mix(in srgb,#ffffff calc(var(--arrive,0)*70%),var(--accent))}
/* Flat --dim, NOT the arrival green. .tools is one reveal unit of ~41 words
   (21 names plus their separators), so "lit while the unit is arriving" spans
   almost the entire beat — the list read as permanently green, and the one
   signal that means something, .ic-lead, had nothing to stand out against.
   The names light when their own icon comes round the ring. That is the
   affordance; the arrival tint was a second one competing with it.

   LIME-GREY AT REST (#65). Flat --dim was the right call against the arrival
   green and it stays the right call — but --dim is a NEUTRAL grey, so the list
   read as body text parked next to the accent system rather than part of it.
   --accent-grey holds the same 5.8:1 the 9.5px labels need while being of the
   lime, which also gives .ic-lead more to stand out FROM, not less: the step
   from lime-grey to full accent is a lift in chroma rather than a colour
   appearing out of nowhere. */
#about .tools .tk{color:var(--accent-grey)}
#about .tools .tk{transition:color .18s,text-shadow .18s}
/* The name whose icon is currently at the front of the ring. Set from orbit()
   in about-plate.js, so the list and the ring are the same signal twice and
   read as one object rather than a list next to a decoration. Deliberately the
   same treatment as :hover — it IS the hover state, driven by the ring. */
#about .tools .tk.ic-lead{color:var(--accent);
  text-shadow:0 0 14px rgba(184,255,0,.45)}

/* The figures are lime, and take the accent voice on hover. They are the only
   numerals on the plate, so this is the one place a font swap reads as an
   event rather than a wobble. */
#about .figs .v{color:var(--accent)}
#about .figs .f:hover .v{font-family:var(--fs);font-style:italic;font-weight:400;
  letter-spacing:0}
#about .figs .f:hover .k{color:var(--muted)}

/* ---- a block lit from the head ----
   When the face part is hovered AFTER its beat has passed, the block does not
   re-reveal — it lifts. A 3px rise and a shadow is enough to say "this one",
   and the accent words come up to full. */
/* Per CHILD, not the parent. Moving the whole block is a slab sliding; moving
   its lines with 26ms between them is the block noticing you. --i is set on
   each unit when the unit list is built. */
/* ---- lift, composed through one variable ----
   The parent and the child were both writing `transform`, so the child simply
   overwrote the parent: a lit block sat at -5px and hovering an item inside it
   set -3px, which moved the item DOWN. Hovering made it recede.

   One custom property fixes it. Every rule sets --lift, the transform is
   written once, and the values compose because the most specific rule wins the
   VARIABLE rather than fighting over the property. */
/* Word spans. inline-block so a mask clips to the word rather than to the
   line box it happens to sit in; the whitespace between them stays real text
   nodes, so wrapping and justification are untouched. */
/* color:inherit is the whole reason this section had no colour in it.
   #how's narration splits words into .w too, and its rule is UNSCOPED:
     .w{--k:0;color:color-mix(in oklab,var(--text) calc(var(--k)*100%),var(--unread-w))}
   With --k:0 that is a flat #383838, and because the plate builds its .w spans
   at runtime it inherited that on every word — which silently overrode the lime
   .ac accents, the --arrive green fade, and --text-2 on every body line. The
   plate carries all of its colour on the LINE, never on the word, so the word
   has to take whatever its parent is currently painted.
   Scoping the plate's own rules protected the page from the plate; this is the
   other direction, which needed protecting too. */
#about .w{display:inline-block;color:inherit}
/* The accent voice as an ARRIVAL, not a hover. Held only while the heading is
   still coming in — this is the one affordance a colour interpolation cannot
   express, because a font swap has no in-between. */
#about .arriving .hv{font-family:var(--fs);font-style:italic;font-weight:400;
  color:var(--accent);letter-spacing:0}
#about .u{--lift:0px;transform:translateY(var(--lift));
  transition:transform .24s var(--ease-out)}
/* transition-delay set HERE, not in the shorthand: the per-item hover rules
   override that shorthand, and a hovered item must answer instantly. Only the
   block lift is allowed to arrive in sequence. */
#about .ann.is-lit .u{--lift:-3px;transition-delay:calc(var(--i,0)*26ms)}
/* Not on Core and Creative: their entries already lift one at a time, and
   lifting the block underneath is two motions saying the same thing.
   Not on 06 at all, and not on 01's name or its quote — those are statements,
   not a list of things to point at. A statement that bobs when you look at the
   face reads as nervous. Only 01's FIGURES lift, because those are items. */
#about [data-a="core"].is-lit .u,#about [data-a="creative"].is-lit .u,#about [data-a="noctvm"].is-lit .u,#about [data-a="bio"].is-lit .name,#about [data-a="bio"].is-lit .qline,#about [data-a="bio"].is-lit .cv{--lift:0px}
/* The lift shadow AND the legibility halo. This rule used to replace the halo
   outright, so hovering a block was the one moment its heading lost its
   separation from the field. */
#about .ann.is-lit h3,#about .ann.is-lit .name{
  text-shadow:0 1px 4px rgba(0,0,0,.92),0 8px 22px rgba(0,0,0,.9)}
#about .ann.is-lit .ac{color:#d4ff4a}
#about .ann.is-lit .lines b{color:var(--muted)}

/* Core left, Creative right — as originally designed. These were briefly
   crossed to chase the hidden-eye problem; that was a misread. The eye fix
   belongs on the MOBILE beats, where the head bleeds half off frame and the
   side it leaves by decides which eye survives. On desktop the head stays
   centred and both eyes are in view, so there was nothing here to fix. */
#about [data-a="core"]{grid-area:core;text-align:right;align-self:start}
#about [data-a="creative"]{grid-area:creative;align-self:start}
#about [data-a="crown"]{grid-area:crown;text-align:center;align-self:start}
/* 05 rises onto the headline's last line: "experience" and "Software agnostic."
   sit as one optical line across the top of the plate. --crown-lift is measured
   in fit(), because the headline is a clamp() and the flex gap is vh-based.
   Desktop only — on narrow the block carries a JS transform of its own and the
   two would fight. */
@media (min-width:1100px){
  #about [data-a="crown"]{transform:translateY(calc(-1 * var(--crown-lift,0px)))}
}
/* 06 keeps the line it always had (centred in its row); 01 comes UP or DOWN to
   meet it. Aligning both to `start` moved the wrong one — it dragged "Currently
   building" up to "Ciprian TITIRE" instead of the other way round. --bio-drop
   is measured in fit(), because it is the difference between two blocks whose
   heights both depend on how the copy wraps at this viewport. */
#about [data-a="bio"]{grid-area:bio;align-self:start;padding-left:22px}
#about [data-a="noctvm"]{grid-area:noctvm;align-self:center}
/* TRANSFORM, not margin-top. As a margin it grew row 2 — 01 is the tallest
   block in it — which pushed row 3 down and clipped "One-man agency" off the
   bottom of the plate, and it also fed back into 06's centred position so the
   measurement had to be iterated. A transform moves the block without touching
   layout: the row keeps its height, 04 stays put, and one measurement is
   exact. Desktop only; on narrow the block carries a JS transform of its own. */
@media (min-width:1100px){
  #about [data-a="bio"]{transform:translateY(var(--bio-drop,0px))}
}
/* 04 rides a little higher than the row's baseline so it sits under the chin
   rather than at the foot of the section. */
#about [data-a="jaw"]{grid-area:jaw;text-align:center;align-self:end;
  margin-bottom:clamp(4px,2.4vh,30px)}

/* ---- the figures ----
   2x2, spanning the exact width of the paragraph above so the bio reads as one
   block rather than a paragraph with a table stuck under it. Figures set large
   in the display face: they are the only numerals left on the plate now that
   01..06 are gone, so they can carry that weight without competing. */
/* The rules are no longer borders on the cells — they are two scalable layers,
   so the lattice can DRAW rather than appear. Horizontals sweep out from the
   left, verticals drop from the top, both off one --draw the choreography sets
   just before the first figure lands (see about-plate.js).
   grid-auto-rows:1fr is load-bearing: the middle lines sit at a flat 50%, which
   is only the row boundary if the two rows are equal. Forcing them equal makes
   that assumption true instead of hoping the labels never wrap. */
#about .figs{--draw:1;margin:15px 0 14px;display:grid;position:relative;
  grid-template-columns:1fr 1fr;grid-auto-rows:1fr}
#about .figs::before,#about .figs::after{content:'';position:absolute;inset:0;
  pointer-events:none;background-repeat:no-repeat;
  background-image:linear-gradient(var(--line),var(--line)),
                   linear-gradient(var(--line),var(--line)),
                   linear-gradient(var(--line),var(--line))}
/* Both axes grow from the CENTRE, so the lattice opens out of its own middle
   rather than unrolling from a corner — same gesture as the brace. */
#about .figs::before{background-size:100% 1px;
  background-position:0 0,0 50%,0 100%;
  transform:scaleX(var(--draw));transform-origin:center}
#about .figs::after{background-size:1px 100%;
  background-position:0 0,50% 0,100% 0;
  transform:scaleY(var(--draw));transform-origin:center}
#about .figs .f{padding:10px 12px 11px;position:relative}
#about .figs .v{display:block;font-size:clamp(26px,2.5vw,38px);font-weight:900;
  letter-spacing:-.035em;line-height:.92;margin-bottom:6px}
#about .figs .k{display:block;font-family:var(--fm);font-size:9px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--dim);line-height:1.4}
#about .figs .f.hascert .k{color:var(--muted);cursor:help}
/* opacity off --seen: a ::after is not text, so the word mask cannot touch it
   and this bullet sat next to "YEARS UI/UX" from the first frame of the page,
   on a section that had revealed nothing. --seen is the unit's own arrival. */
#about .figs .f.hascert .k::after{content:'●';color:var(--accent);font-size:6px;
  vertical-align:middle;margin-left:6px;opacity:var(--seen,0)}

/* Certificate tooltip. Fails soft: if the image is missing the card still
   appears with its caption, so a missing asset is never a broken hover. */
#about .cert{position:absolute;left:0;bottom:calc(100% + 10px);width:230px;
  background:#101010;border:1px solid var(--line);padding:8px;z-index:20;
  opacity:0;visibility:hidden;transform:translateY(4px);
  transition:opacity .16s,transform .16s,visibility .16s}
#about .figs .f.hascert:hover .cert{opacity:1;visibility:visible;transform:none}
#about .cert img{display:block;width:100%;height:auto;border:1px solid var(--line)}
#about .cert span{display:block;font-family:var(--fm);font-size:9px;color:var(--dim);
  letter-spacing:.08em;text-transform:uppercase;margin-top:7px}

/* Same reason as the certificate bullet: a border is not text, so the underline
   of "Download CV" was drawn before the link's own words existed. */
#about .cv{font-family:var(--fm);font-size:11px;color:var(--accent);text-decoration:none;
  border-bottom:1px solid color-mix(in srgb,rgba(184,255,0,.35) calc(var(--seen,0)*100%),transparent);
  padding-bottom:2px}
/* The container carries it too, not just .tk — the separators between the 21
   names inherit from here, and a neutral slash between two lime-grey names is
   the one thing that would give the tint away as a per-word override. */
#about .tools{font-family:var(--fm);font-size:clamp(9.5px,.78vw,11px);color:var(--accent-grey);
  line-height:1.75;display:block;margin-top:7px}
/* 06 floats. Done in CSS 3D rather than as a plane in the icon pass: it stays
   real DOM, so it lazy-loads, stays crisp at any DPR, and needs no unprojection
   to sit where the layout already puts it. perspective on the wrapper, tilt on
   the child, and a slow idle drift so it is never quite still. */
#about .shot-wrap{margin-top:11px;max-width:250px;perspective:820px;
  perspective-origin:50% 50%}
/* THREE EDGES became one (#55). This had a border, then a `0 0 0 1px` white
   ring starting immediately outside it, then a 40px black blur — on a plate
   that sits over the dither field, which is precisely the wide-layer smear the
   shadow tokens exist to avoid. --sh-lg is the layered stack with no ring, so
   the border is the only stroke, and the black stays tight enough that it ties
   the photo to the plate instead of hazing it.
   Hover lifts the stack and warms the BORDER rather than painting a second
   lime ring outside it — same signal, still one edge. */
#about .shot{border:1px solid var(--line);display:block;width:100%;height:auto;
  transform-style:preserve-3d;will-change:transform;
  box-shadow:var(--sh-lg);
  transition:box-shadow .3s,border-color .3s}
#about .shot-wrap:hover .shot{box-shadow:var(--sh-xl);
  border-color:rgba(184,255,0,.32)}
#about .link{font-family:var(--fm);font-size:11px;color:var(--accent);text-decoration:none;
  display:inline-block;margin-top:7px}

/* ================= mobile: the ring, played one card at a time =================
   NOT a stack. Stacking makes it readable and throws away both things the
   section is built on — one viewport per section, and the head as the layout.
   So the pin stays, the head stays, and the beats MOVE things instead: each
   block travels through from its own side of the ring while the head slides the
   other way and bleeds off the opposite edge. The anatomy still assigns
   position; on a phone it just does it sequentially.

   (An earlier stack also had a hard bug: .plate stayed sticky at ~1750px inside
   the pin, so 988px of it was unreachable. Pinning properly avoids that class
   of problem entirely, because nothing ever exceeds the viewport.) */

@media (hover:hover) and (pointer:fine){
  /* .is-lit, not :hover. These were keyed to hovering the BLOCK, which by
     design no longer happens — the head is the control surface now, so the
     titles simply stopped reacting. .is-lit is the state the face hover sets,
     so pointing at an eye swaps its title into the accent voice, which is what
     hovering the block used to do. No media gate needed on this half: .is-lit
     is only ever set by a real pointer, and never on touch. */
  #about [data-a="core"]:hover .hv,#about [data-a="creative"]:hover .hv,#about [data-a="noctvm"]:hover .hv{
    font-family:var(--fs);font-style:italic;font-weight:400;
    color:var(--accent);letter-spacing:0}
}
#about [data-a="core"].is-lit .hv,
#about [data-a="creative"].is-lit .hv,
#about [data-a="noctvm"].is-lit .hv{
  font-family:var(--fs);font-style:italic;font-weight:400;
  color:var(--accent);letter-spacing:0}
/* On a pointer, .hv is a hover affordance and the rules above are the whole
   story. On a phone there is no hover, so the same emphasis is expressed as a
   STATE OF THE BEAT instead — see the narrow block at the foot of this file. */
@media (prefers-reduced-motion:reduce){
  #about .u,#about .ann .lines li,#about .figs .f{transition:color .18s!important;--lift:0px!important}
  #about .cv:active,#about .link:active{transform:none}
}
@media (hover:hover) and (pointer:fine){
  /* -4px, not -9. Nine was a jump; four is an acknowledgement. The colour is
     already carrying the signal — the lift only has to confirm it. */
  #about .ann .lines li:hover{color:var(--accent);--lift:-4px}
  #about .ann .lines li:hover b{color:var(--accent)}
  #about .figs .f:hover{--lift:-4px}
  /* Each tool answers on its own. */
  #about .tools .tk:hover{color:var(--accent)}
}
@media (prefers-reduced-motion: reduce){
  #about .shot{transform:none!important;box-shadow:none}
}
@media (max-width:1099px){
  #about .plate{padding-bottom:56px;gap:8px}
  /* The font-size override is gone so the rule above — .how-h's own expression
     — reaches the phone too. max-width stays: 13ch of a 34px face is narrower
     than the column, and this headline is meant to use the full width. */
  #about .plate-h{max-width:none}
  /* THE TITLE SITS ON SERVICES' LINE. Measured on an S25: every section's label
     rests at 32 (that was #56), but the title beneath it did not follow —
     services puts 40px between them and #how and #about put 24, so their titles
     sat 16px higher than his eye expected.

     RELATIVE, so the plate's own box is untouched. A margin here would have
     taken 16px off .stage, which is flex:1 and is what the head is sized
     against — and this plate is a pinned, viewport-sized box with zero slack,
     so anything that eats height has to come out of something. Painting it in
     place costs nothing. #how has the same rule for the same reason, after a
     margin there pushed its narration into the floating CTA. */
  #about .phead{position:relative;top:16px}
  /* 8px of plate gap put the headline 21px under the label where #how puts it
     37px. The label carries the difference rather than the plate's gap, which
     is shared with everything else stacked in the plate. Same idiom as
     `html.touch #how .sec-head-block .s-label{margin-bottom:24px}`. */
  #about .s-label{margin-bottom:16px}
  /* overflow:clip is required, not cosmetic. Blocks parked offstage sit up to a
     full viewport past the edge, and an unclipped translated element still
     counts toward scrollWidth — the document grew to 1036px inside a 420px
     viewport, which gave the whole page horizontal scroll and carried the
     fixed harness bar out of reach. `clip` rather than `hidden` so it does not
     become a scroll container. */
  /* ── the choreography, and its fallback ────────────────────────────────
     EVERYTHING below is gated on .plate-live, a class about-plate.js adds only
     once it is actually running. Ungated, these rules park all six blocks at
     opacity:0 on top of one another and NOTHING in CSS ever brings them back —
     only the per-frame beat code does. So any failure of that script left the
     whole section blank on a phone: no error, no clue, just nothing.

     It is not hypothetical. The script bails deliberately on `!window.THREE`,
     so a blocked or slow-failing three.js CDN triggers it, and so does WebGL
     being unavailable — `new THREE.WebGLRenderer` throws inside init and takes
     the IIFE with it. Desktop degrades fine, because the words are only masked
     BY the script; the phone layout was the one that could not.

     Without the class the section falls back to an ordinary stack: blocks in
     flow, one after another, plate height auto so they have somewhere to go.
     Ugly on a phone. Readable, which blank is not. */
  #about:not(.plate-live) .plate{height:auto;min-height:100vh}
  #about:not(.plate-live) .ring{position:relative;display:block;height:auto}
  #about:not(.plate-live) .ann{position:relative;margin-bottom:34px;
    text-align:left;padding-left:0}
  #about:not(.plate-live) .ann:last-child{margin-bottom:0}

  /* ── NOTHING SLIDES OFF A SHARP EDGE ──────────────────────────────────────
     A block travelling out used to be cut by the ring's edge with a razor. His
     words: "the text is being clipped (looks like overflow-hidden) ... kinda
     like all others do but this is noticeable because they are left right and
     padded."

     The ring BLEEDS OUT to the screen edges and pads itself back in by the same
     gutter. That is the whole trick: `left:0` on a block still resolves against
     the padding box, so every resting position is exactly where it was, and the
     20px of new space either side is somewhere a fade can live without ever
     touching copy that has come to rest.

     So the mask is opaque across the entire reading area and only falls away in
     the gutter — a word leaving the frame dissolves into it instead of being
     guillotined. Vertical is left alone on purpose: 05 rests 11px below the
     ring's top, and a fade there would eat it. */
  #about.plate-live .ring{position:absolute;inset:0;display:block;height:100%;overflow:clip}
  /* ONLY WHILE SOMETHING IS MOVING, and that is the whole design of it. The
     copy rests flush with this box's edge — that is the gutter, the line the
     headline sits on — so a permanent fade there would eat the first characters
     of every block at rest.

     `.sliding` is set by about-plate.js while any block is actually travelling.
     There is no pop when it goes on or off, because at that moment nothing is
     near the edge for the fade to act on.

     (The obvious alternative was to bleed this box out to the screen edges and
     pad it back in, so the fade could live in the gutter. It does not work: an
     absolutely positioned child's containing block is the PADDING box, which
     starts at the border edge — padding does not inset it. Every block jumped
     to x 0 and went full width. bio survived only because it is position:
     relative and therefore laid out in flow.) */
  #about.plate-live .ring.sliding{
    /* --edge is written per frame by about-plate.js, scaled by how hard the
       block is travelling, so the fade opens and closes with the movement
       instead of snapping on at a fixed width. This is only the fallback for
       the frame before the first write. */
    --edge:0px;
    mask-image:linear-gradient(to right,
      transparent 0, #000 var(--edge),
      #000 calc(100% - var(--edge)), transparent 100%);
  }
  /* Every block occupies the same place. Only one is ever on stage, so they can
     all sit centred and let the transform decide who is here. */
  /* left:0, NOT 5vw. The ring already starts at the page gutter, because the
     plate is padded by it — so 5vw was a SECOND indent on top of it, and every
     block of copy sat 19px right of the label and the headline directly above
     them. Measured on an S25: label and headline at x 20, every block at 39.
     Nothing was buying anything with that inset; the blocks are one at a time
     and have the whole ring to themselves. Zero here means "the gutter", at
     every width, without this rule needing to know what the gutter is. */
  #about.plate-live .ann{position:absolute;left:0;right:0;top:50%;
    transform:translate3d(0,-50%,0);
    text-align:left!important;padding:0!important;margin:0!important;
    opacity:0;pointer-events:none;will-change:transform,opacity}
  #about.plate-live .ann.on{pointer-events:auto}
  /* On the two side beats the head keeps exactly half the frame, so the copy
     takes the other half rather than lying across it.
     side-l lands on the gutter like everything else. side-r CANNOT — it is on
     the right half because the head has the left one — so it takes the mirror
     of the same line instead, flush to the right gutter. Same 4vw-vs-gutter
     mismatch as above, same fix. */
  /* 57% is a DEFAULT now, not a constant. The copy box on a side beat is the
     one number that decides whether the head can grow: the head takes the other
     half of the frame, so every point of width the copy gives back is room the
     head can have. --side-w is written per beat by the bench's dial.

     --wrap-gap is the second half of the same idea. A rectangle beside a round
     head wastes the space above and below its widest point, so the copy can
     hug the silhouette instead: a floated shim carrying shape-outside, sized
     from the head's OWN projected circle each frame (about-plate.js measures
     it) plus whatever breathing room the dial asks for. 0 turns it off and the
     column goes back to being a plain rectangle. */
  #about.plate-live .ann.side-r{left:auto;right:0;width:var(--side-w,57%)}
  #about.plate-live .ann.side-l{right:auto;left:0;width:var(--side-w,57%)}
  /* 03's copy sits on the RIGHT because the head has the left — so it aligns
     right, flush to its own gutter, ragged edge toward the head. Left-aligned
     it started against the head and frayed out at the screen edge, which is the
     wrong way round for a block that belongs to that side.
     !important because .ann sets text-align:left the same way, and this is the
     one case that has to win. */
  #about.plate-live .ann.side-r{text-align:right!important}

  /* ── .hv: THE TWO STATES SWAPPED, ON TOUCH ────────────────────────────────
     His call: "swap the hover state with the normal one ... when entering the
     text enters at sans-serif white, then when it settles it emphasizes and
     turns into sans-serif white back when exits."

     On a pointer the accent voice is a hover, and there is an arrival flourish
     (.arriving) besides. Neither reaches a phone: there is no hover, and the
     arrival version put the emphasis on the word while it was still moving,
     which is the moment it is least readable and least earned.

     So on touch the word arrives PLAIN, turns once the block has come to rest,
     and goes plain again on the way out. .settled is exactly the hold — see
     about-plate.js — so the emphasis lasts as long as the beat is standing
     still to be read, and not a frame longer.

     Specificity: (1,3,0) here beats both `#about .arriving .hv` and the
     per-block hover rules at (1,2,0), so the arrival flourish is off on touch
     without needing !important. */
  #about.plate-live .ann .hv{
    font-family:inherit; font-style:normal; font-weight:inherit;
    color:inherit; letter-spacing:inherit;
  }
  #about.plate-live .ann.settled .hv{
    font-family:var(--fs); font-style:italic; font-weight:400;
    color:var(--accent); letter-spacing:0;
  }

  /* The shim floats toward the HEAD's side and carries the wrap shape. It has
     no content and no background — it exists only to bend the line boxes
     around it. Sized and shaped inline by about-plate.js from the measured
     silhouette; everything here is what stays true whatever those numbers are. */
  #about.plate-live .ann .wrap-shim{
    display:none; pointer-events:none;
    /* shape-margin rather than a padded circle: it keeps the shape honest
       (still the head's real radius) and pushes the text off it by a stated
       amount, which is the thing being tuned. */
    shape-margin:var(--wrap-gap,10px);
  }
  /* side-l means the copy is on the LEFT, so the head is on the right, so the
     shim floats right. The two are always opposites — deriving one from the
     other by hand is how they end up disagreeing. */
  #about.plate-live .ann.side-l.wrapping .wrap-shim{display:block;float:right}
  #about.plate-live .ann.side-r.wrapping .wrap-shim{display:block;float:left}

  /* ── 01, THE FIGURES LEAVE THEIR TABLE (#64) ──────────────────────────────
     His call: the four numbers come out of the lattice and go around the head,
     "2 on the left aligned to left and 2 in the right aligned to right".

     It is not decoration. 01 is the one beat that could not be composed with
     the tools it had, and the reason was measurable: a 301px full-width slab in
     a 554px stage, with the floating CTA wanting the bottom 119px, leaves the
     head 134px. There is no arrangement of that rectangle that works. Splitting
     it into two narrow columns with a lane down the middle changes the shape of
     the problem — the head now lives INSIDE the block's own height rather than
     needing a band above it, and the bottom-right corner the pill owns stops
     carrying copy at all.

     grid-auto-flow:column with two rows is what puts 1,2 on the left and 3,4 on
     the right. Reading order in the DOM is unchanged, which matters twice: the
     word cascade runs in document order, and so does the screen reader.

     --fig-lane is the gap the head stands in. Written by the bench's dial as a
     percentage of the block, defaulted to something sane rather than tuned
     blind here. */
  #about.plate-live [data-a="bio"] .figs{
    grid-auto-flow:column;
    grid-template-columns:auto auto;
    grid-template-rows:auto auto;
    justify-content:space-between;
    /* NARROW COLUMNS, WIDE LANE. The lane is not set directly — it is whatever
       two fixed columns leave between them, which is the honest way round: the
       figures need as much width as their content needs and not a pixel more,
       and the head gets the rest.

       --fig-col is deliberately tight enough that the labels wrap to two lines
       under their number (PRODUCTION / APPS, YEARS ON / THE WEB). His call, and
       it is the whole reason the lane can be wide: at their natural width the
       columns ate 200 of 344px and the head had 144 to live in — so it filled
       its lane, and any pointer movement slid it into the numbers. Two-line
       labels roughly halve the columns and the head gets ~200px of room to
       drift inside without touching anything. */
    grid-template-columns:var(--fig-col,74px) var(--fig-col,74px);
    row-gap:14px;
    margin:18px 0 14px;
    /* The two rows STRADDLE the head rather than sitting in a short block
       beside it — one figure level with the crown, one with the jaw. That is
       what "around the head" means, and without it the four numbers are a
       112px band against a head three times its height, which reads as the head
       having fallen through them.
       --fig-h is the head's own measured height, written by about-plate.js each
       frame; align-content pushes the rows to the ends of it. */
    /* ABSOLUTE, AND HUNG FROM THE MIDDLE. In flow this could not do what he
       asked: the block's bottom is pinned above the floating CTA, so a taller
       figures box pushed the block's TOP up — the upper row moved and the lower
       one stayed, which is the opposite of separating.

       Out of flow, anchored by its own centre, both rows open away from the
       same line — and that line is where the head is, so the numbers separate
       around the head instead of dragging it about.

       --fig-band is the room the head gets, and it is what the copy below is
       padded off, so changing the SPREAD cannot move the name.
       --fig-sep is the spread itself. Two dials because they are two
       questions: how big is the head, and how far apart are its numbers. */
    position:absolute; left:0; right:0;
    top:calc(var(--fig-band,240px) / 2);
    transform:translateY(-50%);
    height:var(--fig-sep,200px);
    align-content:space-between;
  }
  /* The band is reserved on the NAME's margin, not as padding on the block —
     .ann carries padding:0!important and would have won. The name is the first
     thing still in flow now that the figures have left it, so its top margin is
     the reserve. */
  /* The copy starts a stated distance below the BOTTOM ROW — not below the
     band. Hanging it off the band meant head room and the gap to the copy were
     the same number: turning head room up moved the copy down by just as much,
     so the numbers never actually got farther from it. Three dials, three
     questions, none of them moving the other two. */
  #about.plate-live [data-a="bio"] .name{margin-top:var(--fig-copy-top,260px)}
  /* No lattice. The rules were drawn for a table with a shared middle; four
     figures standing apart have no middle to share, and the ::before/::after
     would draw a cross through the head. --draw keeps its meaning for the
     desktop grid, which still has the table. */
  #about.plate-live [data-a="bio"] .figs::before,
  #about.plate-live [data-a="bio"] .figs::after{display:none}
  /* The padding existed to hold cells off the rules. With the rules gone it is
     just a dent in the alignment — the left pair has to sit ON the gutter, the
     same line the name and the quote sit on. */
  #about.plate-live [data-a="bio"] .figs .f{padding:0}
  #about.plate-live [data-a="bio"] .figs .f:nth-child(-n+2){text-align:left}
  #about.plate-live [data-a="bio"] .figs .f:nth-child(n+3){text-align:right}
  /* The label wraps inside its column instead of setting the column's width.
     line-height comes down because two lines of 9px mono at 1.4 is a taller
     stack than the number it sits under deserves. */
  #about.plate-live [data-a="bio"] .figs .k{white-space:normal;line-height:1.25}
  /* The certificate card hangs above its figure and is 230px wide, which is
     most of a phone. On the right-hand pair it would run off the edge, so it
     anchors to the right there instead. */
  #about.plate-live [data-a="bio"] .figs .f:nth-child(n+3) .cert{left:auto;right:0}

  /* ── 01: THE HEAD AND ITS NUMBERS COME FIRST ──────────────────────────────
     His call: the text block goes UNDER the head, and the numbers stay where
     they are relative to it. So the figures — which the head stands inside —
     rise to the top of the block and the name and quote fall below them.

     CSS order, NOT a DOM move. The document order is name, quote, figures, CV,
     and it is right there for three separate reasons: the desktop grid lays out
     from it, a screen reader reads a person's name before their statistics, and
     the word cascade runs in document order. Reordering the source would have
     had to be undone in all three places. This is the one place the visual
     order differs, so this is where it is said.

     The consequence, stated rather than discovered later: the cascade still
     reveals name, then quote, then the figures — so on this beat the copy
     arrives below the head first and the numbers punctuate around it after. */
  #about.plate-live [data-a="bio"]{
    display:flex; flex-direction:column; align-items:flex-start;
    position:relative;          /* the absolute figures hang from this */
  }
  #about.plate-live [data-a="bio"] .figs{order:-1; width:100%}
  #about.plate-live [data-a="bio"] .name,
  #about.plate-live [data-a="bio"] .qline{width:100%}
  /* The figures led the block, so their top margin is now the gap under the
     headline rather than the gap under the quote — and the quote needs the
     space the figures used to leave beneath them. */
  #about.plate-live [data-a="bio"] .figs{margin:0 0 22px}
  /* 01 carries the most words, and it is the only block that reads as a
     paragraph rather than a list, so it gets a little more size on a phone. */
  #about .ann p.qline-l{font-size:clamp(15px,4.3vw,20px);max-width:none}
  /* ...AND EVERY OTHER BEAT FOLLOWS IT. His call. 01's quote was the only copy
     on the plate sized for a phone — one expression at 4.3vw, 16.5px at 384 —
     while the list entries and the paragraphs were still on the desktop's
     clamp(12.5px,1vw,14.5px), which pins at its 12.5px floor on every handset
     made. So 01 read as the section's voice and the other five read as
     footnotes to it.
     Same expression, not a matching number: 4.3vw means they now grow together
     at every width instead of agreeing at one. The 9.5px mono micro-labels
     stay where they are — 01's own label is 9px against its 16.5px body, so
     holding them puts the other beats on 01's ratio as well as its size. */
  #about.plate-live .ann p,
  #about.plate-live .ann .lines li{font-size:clamp(15px,4.3vw,20px)}
  #about [data-a="crown"],#about [data-a="jaw"]{text-align:left!important}
  #about .figs{max-width:none}
  #about .shot-wrap{max-width:62vw}
  #about-overlay{display:none}          /* leaders need a ring to point across */
}
