/* ============================================================
   VOIDSPLUNKER.std — identity hub
   Cyber-Y2K × grunge zine × artsy. Acid green on charcoal.
   Self-contained; independent of the Numidea Labs stylesheet.
   ============================================================ */
:root{
  --ink:#0a0b0d;          /* near-black */
  --ink-2:#101216;
  --panel:#14171c;
  --paper:#ece9dd;        /* off-white */
  --paper-dim:#8f9488;
  --faint:#787f72;        /* was #565b52: 2.83:1 on --ink, used as text */
  --acid:#b6ff2e;         /* primary acid green */
  --acid-dim:#7fbf1f;
  --acc-text:#b6ff2e;     /* acid used AS TEXT (darkens in light theme) */
  --cyan:#4de2ff;         /* Y2K aberration */
  --magenta:#ff2e97;
  --line:#22262c;
  --line-2:#333a41;
  --mono:"Space Mono", ui-monospace, monospace;
  --disp:"Syne", system-ui, sans-serif;
  --ease:cubic-bezier(.16,1,.3,1);
  --gut:clamp(18px,4vw,64px)}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
  background:var(--ink);color:var(--paper);
  font-family:var(--disp);line-height:1.5;overflow-x:hidden;
  -webkit-font-smoothing:antialiased;}
/* The page glow lives on its own fixed layer. It was background-attachment:
   fixed on <body>, which Chrome cannot composite: the whole viewport was
   repainted on every scroll frame. A fixed pseudo-element is composited once
   and simply stays put. */
body::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background-image:
    radial-gradient(120% 90% at 80% -10%, rgba(182,255,46,.10), transparent 60%),
    radial-gradient(90% 80% at 10% 110%, rgba(77,226,255,.06), transparent 60%)}
a{color:inherit;text-decoration:none}
/* skip link: off screen until it takes focus; the ink is fixed because
   --ink turns light in the light theme and --acid stays a light green */
.skip{position:fixed;top:8px;inset-inline-start:8px;z-index:30;padding:10px 16px;border-radius:8px;
  background:var(--acid);color:#0a0b0d;font-family:var(--mono);font-size:13px;font-weight:700;
  transform:translateY(-150%);transition:transform .2s var(--ease)}
.skip:focus{transform:none;outline:2px solid var(--paper);outline-offset:2px}
#collection:focus{outline:none}   /* the skip link's target */
@media (prefers-reduced-motion:reduce){.skip{transition:none}}
.mono{font-family:var(--mono)}
.acc{color:var(--acc-text)}
.dim{color:var(--faint)}

/* ---- global grain + scanlines ---- */
/* grain without a blend mode: an overlay-blended layer over the whole
   viewport made the GPU re-blend every pixel of every scroll frame */

/* ============================================================
   AMBIENT + PARALLAX SYSTEM
   Calm by construction: long durations, low amplitude, nothing
   ever snaps. Pointer and scroll parallax are composed through
   CSS variables so the two never fight over `transform`.
     --px/--py  pointer offset   (set by app.js)
     --sy       scroll offset    (set by app.js)
   ============================================================ */
[data-depth],[data-parallax]{
  transform:translate3d(var(--px,0px),calc(var(--py,0px) + var(--sy,0px)),0);
  will-change:transform}

/* No filter:blur — a 60px blur over a layer 140% of the viewport was
   re-applied by the compositor on every frame, and the fields are already
   soft radial gradients. No blend mode either, for the same reason. */

/* ---- drifting geometry: hand-drawn SVG, slow rotation ---- */

/* ---- gentle scroll reveal: rise + fade, staggered by JS ----
   Gated on html.reveal-armed, which app.js sets only once its observer is
   running. Without that script (disabled, blocked, a 404, an error first)
   nothing is hidden: the old rule hid every block unconditionally, and with
   scripts off 26 blocks — 16 of them focusable links — stayed invisible. */
   The gate sits in :where() so it adds no specificity: the reveal rules weigh
   what [data-reveal] always weighed, and hover lifts on cards and links
   (.link:hover, .scard:hover) still win over .seen, as before the gate. */
:where(.reveal-armed) [data-reveal]{opacity:0;transform:translate3d(0,18px,0);
  transition:opacity 1s var(--ease),transform 1.1s var(--ease);
  transition-delay:var(--rd,0ms)}
:where(.reveal-armed) [data-reveal].seen{opacity:1;transform:none}

/* text that only screen readers and voice control need */
.vh{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;border:0;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}

/* ---- breathing accents: barely-there pulse on live marks ---- */
@keyframes breathe{0%,100%{opacity:.55;transform:scale(1)}50%{opacity:1;transform:scale(1.06)}}

/* ============================= HERO ============================= */
/* .hero already clips (overflow:hidden below): the giant .ghost word hangs past
   the viewport by design and is framed by it. A bounding-rect overflow check
   reports it anyway — it has to resolve the clipping ancestor first. */
.hero{position:relative;min-height:100svh;padding:clamp(16px,3vw,28px) var(--gut) 0;
  display:flex;flex-direction:column;overflow:hidden;isolation:isolate}

/* top bar */
.topbar{position:relative;z-index:3;display:flex;align-items:center;gap:16px;
  padding-bottom:clamp(20px,5vh,56px)}
.brandtag{font-family:var(--mono);font-weight:700;font-size:13px;letter-spacing:.14em;text-transform:uppercase}
.topbar .spacer{flex:1}
.topbar .mono{font-size:11px;letter-spacing:.2em;white-space:nowrap}   /* "EST — MMXXV" split in two on phones */
.topbar .dim{color:var(--paper-dim)}   /* --faint over the hero art measured 4.24:1 */

/* hero layout */
.hero-grid{position:relative;z-index:2;flex:1;display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(24px,5vw,64px);align-items:center;padding-bottom:clamp(40px,8vh,80px)}

/* ---- identity ---- */
.identity{container-type:inline-size}
.eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--acc-text);
  display:flex;align-items:center;gap:10px;margin-bottom:clamp(16px,3vh,28px)}
.blip{width:8px;height:8px;border-radius:50%;background:var(--acid);box-shadow:0 0 12px var(--acid)}

/* Sized from the COLUMN, not the viewport. Syne 800 runs roughly twice the
   width of the fallback this clamp was tuned against, so the real face
   overflowed everywhere — "VOIDSPLUNKER.std" wanted 1465px in a 739px column
   and was clipped behind the portrait, with 132-223px of horizontal overflow on
   the page. A vw clamp cannot express it either: the column is NARROWER at 1280
   (585px, two-up with the portrait) than at 768 (707px), so viewport width and
   available width do not move together. cqw tracks the column itself, and these
   identities are unbreakable tokens with nowhere to wrap. */
.cycler{font-family:var(--disp);font-weight:800;letter-spacing:-.03em;line-height:.94;
  font-size:clamp(17px,6.2cqw,58px);margin-bottom:clamp(14px,2.4vh,22px)}
/* The heading reserves two lines. Measured across widths, the five identities
   render as either one line or two — never more — so two lines of the heading's
   own line-height is the exact reservation that lets the text swap without ever
   changing the box, and everything below it stays put. Reserving WIDTH instead
   (min-width:20ch) was the wrong axis: it blew the box out to 1247px and left
   the shift in place, because the wrap count was what actually varied.
   The caret went with it — a flex child after the text, it slid on every swap. */
.cycler{min-height:1.88em}   /* 2 × the .94 line-height above */
.cy-line{display:inline-flex;align-items:baseline;gap:.08em;flex-wrap:wrap;max-width:100%}
/* The handle is one unbreakable token sized to fit its column. With a
   reader's own text spacing (WCAG 1.4.12: letter-spacing .12em) it no longer
   fits, and the hero's overflow:hidden cut 19-42px off it; it may now wrap
   rather than be clipped. At normal spacing it fits, so nothing changes. */
.cy-text{min-width:0;overflow-wrap:anywhere}
.cy-text{transition:opacity .26s ease}
.cy-text.swapping{opacity:0}
.cy-text{color:var(--paper)}
@keyframes caret{0%,50%{opacity:1}51%,100%{opacity:0}}

/* em, not ch. ch is a font metric: these are Google-hosted faces, so on a
   blocked or slow network the measure changed when they landed. */
.philo{font-family:var(--disp);font-weight:600;font-style:italic;font-size:clamp(16px,2vw,22px);
  color:var(--paper);max-width:18.08em;margin-bottom:clamp(22px,4vh,34px);min-height:2.5em;
  border-left:2px solid var(--acid);padding-left:14px;transition:opacity .4s}

.meta{list-style:none;display:grid;gap:9px;font-size:12.5px;max-width:26.45em}
.meta li{display:grid;grid-template-columns:64px minmax(0,1fr);gap:14px;align-items:baseline;
  border-bottom:1px dashed var(--line);padding-bottom:9px}
.meta b{color:var(--faint);font-weight:400;letter-spacing:.18em;font-size:10px}
.meta span{color:var(--paper-dim)}
.meta .ok{color:var(--acc-text)}

/* ---- avatar ---- */
.avatar{position:relative;justify-self:center;width:min(100%,420px);aspect-ratio:5/6}
.frame{position:absolute;inset:0;border:1px solid var(--line-2);background:
  linear-gradient(180deg,rgba(182,255,46,.04),transparent 40%),var(--ink-2);overflow:hidden}

.portrait{position:absolute;inset:0;display:grid;place-items:center;overflow:hidden}
/* The glitchbar is gone. It swept a coloured bar down the portrait forever by
   animating `top` — a layout property, so every frame of it was a layout shift
   on a page that never stopped animating. Decoration that cost the page its
   stability, and the loudest piece of the "glitch" vocabulary on it. */
.frame-cap{position:absolute;left:10px;bottom:10px;z-index:3;font-size:10px;letter-spacing:.12em;
  color:var(--paper-dim);background:rgba(10,11,13,.7);padding:4px 7px;border:1px solid var(--line)}
.frame-cap .await{color:var(--faint);font-style:normal}

/* scroll cue */
.scrollcue{position:relative;z-index:3;display:flex;align-items:center;gap:12px;justify-content:center;
  padding:clamp(14px,3vh,22px) 0;font-size:11px;letter-spacing:.2em;color:var(--paper-dim);border-top:1px solid var(--line)}
.scrollcue .arr{color:var(--acc-text)}

.scrollcue:hover{color:var(--acid)}
/* inset: the cue is the last thing in the hero, whose overflow:hidden cut the
   bottom of an outside ring */
.scrollcue:focus-visible{outline:2px solid var(--acc-text);outline-offset:-4px}

/* ============================= LINKS ============================= */
.links{position:relative;z-index:2;padding:clamp(48px,10vh,110px) var(--gut) clamp(28px,6vh,60px);border-top:1px solid var(--line);isolation:isolate}
.links-head{margin-bottom:clamp(28px,5vh,52px)}
/* Sized from its own column, like the identity heading. "EVERY&nbsp;WORLD." is
   one unbreakable token and was the page's real horizontal overflow once Syne
   replaced the narrower fallback the vw clamp had been tuned against. */
.links-head{container-type:inline-size}
.links-head h2{font-family:var(--disp);font-weight:800;letter-spacing:-.03em;line-height:.9;
  font-size:clamp(26px,7.5cqw,120px);margin:10px 0 14px;overflow-wrap:break-word}
.links-sub{font-family:var(--mono);font-size:13px;color:var(--paper-dim)}
.links-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px}

/* The archive was eighteen undifferentiated tiles. These headers are the
   grouping the source comments already described, and they give the
   generated drawings a size at which they actually read — at the 18px
   the footer headings offered, they were smudges. */
.lgroup{grid-column:1/-1;display:flex;align-items:center;gap:16px;
  margin:clamp(14px,3vh,28px) 0 2px;padding-bottom:12px;border-bottom:1px dashed var(--line)}
.lgroup:first-of-type{margin-top:0}
.lgroup .ill{flex:none;width:60px;height:60px;background:currentColor;color:var(--acc-text);
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:center;mask-position:center;
  -webkit-mask-size:contain;mask-size:contain;
  -webkit-mask-source-type:luminance;mask-mode:luminance}
.lgroup-t{display:flex;flex-direction:column;gap:3px;min-width:0;
  font-family:var(--mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--paper)}
.lgroup-t i{font-family:var(--disp);font-style:normal;font-weight:500;font-size:13px;
  letter-spacing:0;text-transform:none;color:var(--faint)}
.ill-design{-webkit-mask-image:url(../assets/illus/hub-design.png);mask-image:url(../assets/illus/hub-design.png)}
.ill-dev{-webkit-mask-image:url(../assets/illus/hub-dev.png);mask-image:url(../assets/illus/hub-dev.png)}
.ill-social{-webkit-mask-image:url(../assets/illus/hub-social.png);mask-image:url(../assets/illus/hub-social.png)}
.ill-studio{-webkit-mask-image:url(../assets/illus/hub-studio.png);mask-image:url(../assets/illus/hub-studio.png)}

.link{position:relative;display:flex;align-items:center;gap:14px;padding:16px;
  border:1px solid var(--line-2);background:linear-gradient(180deg,rgba(255,255,255,.02),transparent);
  transition:transform .3s var(--ease),border-color .3s,background .3s,box-shadow .3s;overflow:hidden}
.link::after{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--b,var(--acid));transform:scaleY(0);transform-origin:bottom;transition:transform .3s var(--ease)}
.link:hover{transform:translateY(-3px);border-color:var(--b,var(--acid));background:rgba(255,255,255,.04);
  box-shadow:0 18px 40px -26px rgba(0,0,0,.9), 0 0 0 1px color-mix(in srgb, var(--b,var(--acid)) 30%, transparent)}
.link:hover::after{transform:scaleY(1)}
.badge{flex:none;width:44px;height:44px;display:grid;place-items:center;font-weight:700;font-size:15px;
  border:1px solid var(--line-2);color:var(--b,var(--acid));background:var(--ink);letter-spacing:0;transition:.3s}
.link:hover .badge{border-color:var(--b,var(--acid));background:var(--b,var(--acid));color:var(--ink);
  transform:rotate(-4deg) scale(1.06)}
.badge{transition:transform .5s var(--ease),background .4s var(--ease),color .4s var(--ease),border-color .4s var(--ease)}
.ltxt{display:flex;flex-direction:column;min-width:0;flex:1}
.ltxt b{font-family:var(--disp);font-weight:700;font-size:16px;letter-spacing:-.01em}
/* wraps rather than truncating with an ellipsis: in the 269px cards at 600px,
   and under a reader's own text spacing, the line lost its end ("my favourite
   build — out n…") */
.ltxt i{font-family:var(--mono);font-style:normal;font-size:11px;color:var(--faint);overflow-wrap:anywhere}
.go{font-family:var(--mono);color:var(--faint);transition:.3s var(--ease)}
.link:hover .go{color:var(--b,var(--acid));transform:translate(2px,-2px)}

/* per-brand accents */
.link[data-brand="behance"]{--b:#3b7bff}
.link[data-brand="dribbble"]{--b:#ea4c89}
.link[data-brand="deviantart"]{--b:#05cc47}
.link[data-brand="artstation"]{--b:#22c6ff}
.link[data-brand="pinterest"]{--b:#ff3b4e}
.link[data-brand="arena"]{--b:#cfd2c8}
.link[data-brand="numidea"]{--b:#34d0e8}
.link[data-brand="github"]{--b:#eceadf}
.link[data-brand="linkedin"]{--b:#3a9bff}
.link[data-brand="instagram"]{--b:#ff5a8a}
.link[data-brand="x"]{--b:#eceadf}
.link[data-brand="youtube"]{--b:#ff3b3b}
.link[data-brand="tiktok"]{--b:#4de8e0}
.link[data-brand="gumroad"]{--b:#ff90e8}
.link[data-brand="email"]{--b:#b6ff2e}
.link[data-brand="tumblr"]{--b:#8fb3d9}
.link[data-brand="telegram"]{--b:#3fa9e8}
.link[data-brand="etsy"]{--b:#f1641e}

/* ============================= RESPONSIVE ============================= */
@media (max-width:860px){
  .hero-grid{grid-template-columns:minmax(0,1fr);gap:clamp(28px,6vh,44px);padding-top:8px}
  .avatar{order:-1;width:min(78%,320px)}
  /* safe-area: the hero runs full-bleed under viewport-fit=cover */
  .hero{padding-left:max(var(--gut),env(safe-area-inset-left));
        padding-right:max(var(--gut),env(safe-area-inset-right))}
  
  body{cursor:auto}
  
}
/* Stacking the portrait above the copy costs a whole screen when the
   screen is short: at 717x512 the avatar alone ran y76→460 of a 512px
   viewport, so the name, roles and status were all below the fold and
   the first thing a visitor saw was an empty image frame. Sit them side
   by side instead when there is width to spare but no height. Not on a
   small portrait phone (320x568 matched this too): there is no width to
   spare, and the copy column, 140px wide, broke the name mid-word
   ("br4vetr / 4veler") and the studio line under the portrait (r3/a). */
@media (max-width:860px) and (max-height:620px) and (min-width:480px){
  .hero-grid{grid-template-columns:minmax(0,1fr) minmax(0,.8fr);align-items:center;gap:clamp(16px,4vw,32px)}
  .avatar{order:0;width:min(100%,240px)}
  .hero{min-height:auto;padding-block:clamp(12px,3vh,20px) clamp(16px,4vh,28px)}
  
}
@media (max-width:520px){
  .meta li{grid-template-columns:56px minmax(0,1fr);gap:10px}
  .links-grid{grid-template-columns:minmax(0,1fr)}
}

/* ============================= LIGHT THEME ============================= */
:root[data-theme="light"]{
  --ink:#e9e7dd;--ink-2:#e0ded3;--panel:#d4d2c5;
  --paper:#14160f;--paper-dim:#494c40;--faint:#63665a;
  --acid:#8fd600;--acid-dim:#6aa300;--acc-text:#357000;
  --cyan:#0aa8cc;--magenta:#e01d80;
  --line:#cccabd;--line-2:#adab9c}
:root[data-theme="light"] body::before{
  background-image:radial-gradient(120% 90% at 80% -10%,rgba(143,214,0,.16),transparent 60%),
                   radial-gradient(90% 80% at 10% 110%,rgba(10,168,204,.08),transparent 60%)}

:root[data-theme="light"] .frame{background:linear-gradient(180deg,rgba(143,214,0,.08),transparent 40%),var(--ink-2)}
:root[data-theme="light"] .frame-cap{background:rgba(233,231,221,.82)}
/* the caption sits over the portrait; --faint drops to ~3.2:1 there */
:root[data-theme="light"] .frame-cap .await{color:var(--paper-dim)}
:root[data-theme="light"] .badge{background:var(--ink-2)}
/* Brand colours are tuned for the dark page; on paper they fall to ~1.1–2.6:1.
   Text keeps a third of the brand hue over the ink colour (≥4.5:1 for every
   brand, including near-white GitHub/X); on hover the brand fills the badge
   and dark ink sits on it. */
:root[data-theme="light"] .badge{color:color-mix(in srgb,var(--b,var(--acid)) 30%,var(--paper))}
:root[data-theme="light"] .link--whq .badge{color:color-mix(in srgb,#ffd23f 30%,var(--paper))}
:root[data-theme="light"] .link:hover .badge{color:var(--paper)}
:root[data-theme="light"] .link{background:linear-gradient(180deg,rgba(0,0,0,.02),transparent)}
:root[data-theme="light"] .link:hover{background:rgba(0,0,0,.04)}

/* ============================= SCROLL POSE (placeholder morph) ============================= */
.portrait{transition:transform .55s var(--ease)}
/* real frames (when added as <img class="pose">): cross-fade */
.portrait .pose{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;
  transition:opacity 1.1s var(--ease),transform 1.4s var(--ease);transform:scale(1.04)}
.portrait .pose.on{opacity:1;transform:scale(1)}
/* once real frames exist the drawn placeholder steps aside */

/* ============================= FOOTER ============================= */
.site-foot{position:relative;z-index:2;border-top:1px solid var(--line);padding:clamp(40px,7vh,72px) var(--gut) clamp(28px,5vh,44px)}
.foot-top{display:grid;grid-template-columns:auto minmax(0,1fr);gap:clamp(20px,4vw,44px);align-items:start;max-width:1200px;margin:0 auto}
.foot-mark{width:52px;height:52px;display:grid;place-items:center;border:1px dashed var(--line-2);border-radius:50%;flex:none}
.foot-mark svg{width:26px;height:26px;fill:none;stroke:var(--acid);stroke-width:1.5}
.foot-bio{font-family:var(--mono);font-size:12.5px;line-height:1.7;color:var(--paper-dim);max-width:42.08em}
.foot-bio b{color:var(--paper);font-weight:700}
.foot-bio .acc{color:var(--acc-text)}

   /* 16px tall was a thumb-sized coin toss */

.foot-mid{max-width:1200px;margin:clamp(26px,4vh,40px) auto 0;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:22px}
.foot-socials{display:flex;flex-wrap:wrap;gap:12px;justify-content:center}
.soc{width:44px;height:44px;display:grid;place-items:center;border:1px dashed var(--line-2);border-radius:14px;
  color:var(--paper-dim);font-family:var(--mono);font-weight:700;font-size:13px;
  transition:transform .25s var(--ease),border-color .25s,color .25s,background .25s}
.soc svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.soc:hover{transform:translateY(-4px);border-color:var(--acid);color:var(--acid);background:rgba(182,255,46,.06)}

/* theme pill (sun · top · moon) */
.theme-pill{display:inline-flex;align-items:center;gap:6px;border:1px dashed var(--line-2);border-radius:999px;padding:5px}
.theme-pill button{width:38px;height:38px;display:grid;place-items:center;border:0;border-radius:50%;cursor:pointer;
  background:transparent;color:var(--paper-dim);transition:.25s var(--ease)}
.theme-pill svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
.theme-pill .tp-top{width:30px;height:30px}
.theme-pill .tp-top svg{width:14px;height:14px}
.theme-pill button:hover{color:var(--paper)}
.theme-pill .tp-sun{color:var(--acid);background:rgba(182,255,46,.08)}
.theme-pill .tp-moon:hover{color:var(--acid)}
:root[data-theme="light"] .theme-pill .tp-sun{background:var(--acid);color:var(--ink)}
:root[data-theme="light"] .theme-pill .tp-moon{background:transparent}
:root[data-theme="dark"] .theme-pill .tp-moon{background:rgba(255,255,255,.06);color:var(--paper)}
:root[data-theme="dark"] .theme-pill .tp-sun{background:transparent;color:var(--paper-dim)}
:root[data-theme="dark"] .theme-pill .tp-sun:hover{color:var(--acid)}
/* Forced colours drop the backgrounds above, which were the only sign of the
   current theme; the pressed button (aria-pressed, kept by app.js) gets a
   system-colour ring instead. */
@media (forced-colors:active){.theme-pill button[aria-pressed="true"]{border:2px solid Highlight}}
/* Without scripts these three buttons do nothing (the head script that sets
   data-theme has not run either), so they are not offered. */
html:not([data-theme]) .theme-pill{display:none}

.foot-legal{max-width:1200px;margin:clamp(26px,4vh,40px) auto 0;display:flex;align-items:center;justify-content:center;gap:6px;
  font-family:var(--mono);font-size:11px;letter-spacing:.06em;color:var(--faint);flex-wrap:wrap}
.foot-legal .heart{color:#ff3b6b;display:inline-flex}
.foot-legal b{color:var(--paper);font-weight:700}
.foot-legal a{color:var(--acc-text)}

@media (max-width:640px){ .foot-top{grid-template-columns:minmax(0,1fr)} .foot-mid{flex-direction:column} }

/* ============================= MOTION-SAFE ============================= */
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;scroll-behavior:auto}
  /* html by name: the html{scroll-behavior:smooth} rule above outranks the
     universal selector, and the viewport scrolls the way html says (the skip
     link, the hero's scroll cue and focus scrolling all glided) */
  html{scroll-behavior:auto}
  .cy-caret{opacity:1}
  [data-reveal],.reveal-armed [data-reveal]{opacity:1;transform:none;transition:none}
  [data-depth],[data-parallax]{transform:none}
  
}

.links-soon{margin-top:18px;font-size:11px;letter-spacing:.12em;color:var(--faint)}

/* ============================= SECTIONS ============================= */
.coll,.design,.social{position:relative;z-index:2;padding:clamp(48px,10vh,110px) var(--gut) clamp(28px,6vh,60px);
  border-top:1px solid var(--line);isolation:isolate}
.coll-head{margin-bottom:clamp(22px,4vh,40px);container-type:inline-size}
.coll-head h2{font-family:var(--disp);font-weight:800;letter-spacing:-.03em;line-height:.9;
  font-size:clamp(26px,7.5cqw,120px);margin:10px 0 14px;overflow-wrap:break-word}

.coll-more{margin-top:18px;font-size:12px;letter-spacing:.12em;text-transform:uppercase}
.coll-more a{display:inline-flex;align-items:center;gap:8px;min-height:44px;color:var(--paper-dim);transition:color .2s}
.coll-more a:hover{color:var(--acc-text)}

/* the viewer — a native <dialog>: focus is trapped and Esc closes it for free */
.lb{margin:auto;width:min(1100px,94vw);max-height:94vh;padding:0;border:1px solid var(--line-2);
  background:var(--ink);color:var(--paper);overflow:visible}

.lb-fig{display:grid;grid-template-rows:minmax(0,1fr) auto;max-height:94vh}
.lb-fig img{display:block;width:100%;height:100%;max-height:calc(94vh - 72px);object-fit:contain;background:var(--ink-2)}
.lb-fig figcaption{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 16px;padding:14px 18px;border-top:1px solid var(--line-2)}
.lb-fig figcaption b{font-size:16px}
.lb-fig figcaption i{font-style:normal;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--faint)}
.lb-fig figcaption a{margin-inline-start:auto;font-size:12px;color:var(--acc-text);min-height:24px;display:inline-flex;align-items:center}
/* z-index: the buttons come before the figure in the source (Close first, for
   focus), and the picture fading in would otherwise paint over them */
.lb-btn{position:absolute;z-index:2;width:44px;height:44px;display:grid;place-items:center;cursor:pointer;
  font:16px var(--mono);color:var(--paper);background:var(--ink);border:1px solid var(--line-2);transition:border-color .2s,color .2s}
.lb-btn:hover{border-color:var(--acid);color:var(--acc-text)}
.lb-btn:focus-visible{outline:2px solid var(--acid);outline-offset:2px}
.lb-close{top:-1px;inset-inline-end:-1px}
.lb-prev{top:40%;inset-inline-start:-1px}
.lb-next{top:40%;inset-inline-end:-1px}
html[dir="rtl"] .lb-prev,html[dir="rtl"] .lb-next{transform:scaleX(-1)}

/* ============================= DESIGN ============================= */

/* ============================= SOCIAL HIGHLIGHTS ============================= */
.social-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr));gap:14px}
.scard{display:flex;flex-direction:column;gap:18px;padding:20px;color:inherit;border:1px solid var(--line-2);
  background:linear-gradient(160deg,color-mix(in srgb,var(--acid) 6%,transparent),transparent 55%);
  transition:transform .3s var(--ease),border-color .3s}
.scard:hover{transform:translateY(-3px);border-color:var(--acid)}
.scard:focus-visible{outline:2px solid var(--acid);outline-offset:3px}
.sc-top{display:flex;align-items:center;gap:10px;font-size:12px;letter-spacing:.08em;color:var(--paper)}
/* the handle wraps rather than ending in an ellipsis (at 320px all three were
   cut: "@br4vetr4ave…") */
.sc-top i{font-style:normal;color:var(--paper-dim);min-width:0;overflow-wrap:anywhere}
.sc-top .go{margin-inline-start:auto}
.scard:hover .go{color:var(--acc-text)}
.sc-big{display:grid;gap:4px}
.sc-big b{font-family:var(--disp);font-weight:800;font-size:clamp(48px,6vw,84px);line-height:.9;letter-spacing:-.04em;color:var(--acc-text)}
.sc-big .sc-word{font-size:clamp(34px,4vw,54px);letter-spacing:-.03em}
.sc-big i{font-style:normal;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--paper-dim)}
.sc-row{display:flex;flex-wrap:wrap;gap:6px 18px;font-size:12px;color:var(--paper-dim)}
.sc-row b{color:var(--paper);font-weight:700}
.sc-thumbs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;margin-top:auto}
/* height:auto — the width/height attributes (there for layout stability) set
   a fixed 501-630px height that overrode aspect-ratio, so the "squares" were
   tall strips the full height of each source picture */
.sc-thumbs img{display:block;width:100%;height:auto;aspect-ratio:1;object-fit:cover;border:1px solid var(--line-2)}
.sc-ig .sc-row span{padding:4px 10px;border:1px dashed var(--line-2)}
@media (prefers-reduced-motion:reduce){
  .scard,
.lb-btn{transition:none}
  .scard:hover{transform:none}
}
:root[data-theme="light"] .lb[open]::backdrop{background:rgba(233,231,221,.9)}

.chapter{--c1:var(--acid);--c2:var(--paper-dim);scroll-margin-top:24px;margin-bottom:clamp(48px,9vh,110px)}
.chapter[data-ch="traveler"]{--c1:#8a7dff;--c2:#b6ff2e}
.chapter[data-ch="sky"]{--c1:#2f6fd8;--c2:#f2d43c}
.chapter[data-ch="noise"]{--c1:#ec3b1e;--c2:#f6a21a}
.chapter[data-ch="ink"]{--c1:#7a4dd8;--c2:#b6ff2e}
.chapter[data-ch="imagination"]{--c1:#ec3b1e;--c2:#f2d43c}

/* 13 characters of Syne 800 overflowed the column at the shared 7.5cqw */
.series .coll-head h2{font-size:clamp(20px,6.3cqw,104px)}

/* 320px phones: both long display headings need a smaller floor */
@media (max-width:360px){.series .coll-head h2,.links-head h2{font-size:6.1vw}}

/* ============================= BENTO =============================
   One system for the whole gallery. Every grid runs on SQUARE units —
   grid-auto-rows equals the column width, computed from the container
   (100cqw) — so a tile spanning C columns and R rows has the shape C:R, and
   each piece gets a tile of its own shape: posters 2:3 (2x3, 4x6), portraits
   1:1 (2x2, 4x4), the Goddard poster 4x7 (its 941x1672 is 0.563; 4x7 is
   0.571). object-fit:cover then crops at most a few px of gap.
   Tile ORDER in the markup is part of the layout: with dense auto-flow it is
   what makes each chapter close flush at 6 columns and at 4 — see BRAND.md
   before reordering. */
.coll,.design,.social{padding-inline:max(var(--gut),calc((100% - 1080px) / 2))}
.chapter{container-type:inline-size;margin-bottom:var(--g,14px)}
.series{--g:clamp(8px,1.2vw,14px)}
/* Rows are square units that may GROW, never shrink: minmax(unit, auto).
   Wherever a text tile fits its span (every width above ~420px at normal
   text spacing) the grid is exactly the square one. Where it did not, the
   tile clipped: at 320px the chapter tiles cut 24-62px off their top (the
   numeral and the "Chapter I · 8 posters" line), and under a reader's own
   spacing (WCAG 1.4.12) the Ink quote lost 27-35px. Now those rows grow and
   the pictures beside them crop a little more. Picture tiles are size-
   contained so their images never push a row — they fill what the grid gives. */
.bento{--cols:6;--u:calc((100cqw - (var(--cols) - 1) * var(--g)) / var(--cols));
  display:grid;grid-template-columns:repeat(var(--cols),minmax(0,1fr));grid-auto-rows:minmax(var(--u),auto);
  grid-auto-flow:dense;gap:var(--g)}
.bento .tile--img{contain:size}
.t-big{grid-column:span 4;grid-row:span 6}
.t-sm,.t-head{grid-column:span 2;grid-row:span 3}
.t-quote{grid-column:span 4;grid-row:span 3}
.t-phead{grid-column:span 2;grid-row:span 4}
.t-pbig{grid-column:span 4;grid-row:span 4}
.t-psm{grid-column:span 2;grid-row:span 2}
.t-ep{grid-column:span 4;grid-row:span 7}
.t-eptext{grid-column:span 2;grid-row:span 7}
@media (max-width:719px){
  .bento{--cols:4}
  .t-phead{grid-row:span 2}
  .t-eptext{grid-column:span 4;grid-row:span 3}
}

/* ---- tiles ---- */
.tile{position:relative;display:block;min-width:0;border-radius:14px;overflow:hidden;background:var(--panel);
  isolation:isolate}
.tile--img{color:inherit;box-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 22px 44px -30px rgba(0,0,0,.9)}
.tile--img img{display:block;width:100%;height:100%;object-fit:cover;
  transition:transform .9s var(--ease),opacity .6s ease}
body.fi .tile img{opacity:0}
body.fi .tile img.ld{opacity:1}
.tile--img:hover img{transform:scale(1.03)}
.tile--img:focus-visible{outline:2px solid var(--acid);outline-offset:3px}
/* the label: quiet until asked for on a pointer, always there on touch */
.tl{position:absolute;left:10px;bottom:10px;max-width:calc(100% - 20px);display:grid;gap:2px;
  padding:8px 11px 9px;border-radius:9px;background:rgba(10,11,13,.8);color:#ece9dd;
  opacity:0;transform:translateY(6px);transition:opacity .35s var(--ease),transform .35s var(--ease)}
.tl b{font-weight:700;font-size:13px;line-height:1.25;overflow-wrap:anywhere}
.tl i{font-style:normal;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:#a9ad9f}
.tile--img:hover .tl,.tile--img:focus-visible .tl{opacity:1;transform:none}
@media (hover:none){.tl{opacity:1;transform:none}}

/* text tiles carry the chapter's two inks as a soft wash */
.chapter{--c1:var(--acid);--c2:var(--paper-dim)}
.tile--text{display:flex;flex-direction:column;justify-content:flex-end;gap:6px;padding:clamp(14px,2.2cqw,26px);
  background:
    radial-gradient(120% 80% at 0% 0%,color-mix(in srgb,var(--c1) 22%,transparent),transparent 60%),
    radial-gradient(90% 70% at 100% 100%,color-mix(in srgb,var(--c2) 12%,transparent),transparent 60%),
    var(--ink-2);
  border:1px solid var(--line)}
.tt-num{margin-bottom:auto;font-family:var(--disp);font-weight:800;line-height:.8;letter-spacing:-.04em;
  font-size:clamp(40px,9cqw,104px);color:transparent;-webkit-text-stroke:1.5px var(--c1)}
.tt-kick{font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--paper-dim)}
.tile--text h3{font-family:var(--disp);font-weight:800;font-size:clamp(20px,3.6cqw,40px);line-height:.95;letter-spacing:-.025em;
  text-transform:uppercase;color:var(--paper);overflow-wrap:anywhere}
.tt-line{font-family:var(--mono);font-size:clamp(11px,1.25cqw,13px);line-height:1.55;color:var(--paper-dim)}
.tile--quote{justify-content:center}
.tt-quote{font-family:var(--disp);font-weight:800;font-size:clamp(17px,2.8cqw,32px);line-height:1.15;letter-spacing:-.015em;
  color:var(--paper);max-width:24ch}
.tt-quote::before{content:"“";display:block;font-size:2.2em;line-height:.6;color:var(--c1)}
.t-eptext .tt-line{font-size:clamp(12px,1.5cqw,15px)}
@media (max-width:719px){
  .t-phead{padding:12px}
  .t-phead .tt-num{font-size:34px}
  .t-phead h3{font-size:18px}
  .t-phead .tt-line{font-size:10.5px;line-height:1.4}
}
:root[data-theme="light"] .tile--text{background:
    radial-gradient(120% 80% at 0% 0%,color-mix(in srgb,var(--c1) 16%,transparent),transparent 60%),var(--ink-2)}

/* ---- design: the same tiles on units shaped like the Behance covers ---- */
.design{container-type:inline-size;--g:clamp(8px,1.2vw,14px)}
.design-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--g);grid-auto-flow:dense;
  grid-auto-rows:calc((100cqw - 2 * var(--g)) / 3 / 1.2785)}
.dtile--lead{grid-column:span 2;grid-row:span 2}
@media (max-width:719px){
  .design-grid{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:calc((100cqw - var(--g)) / 2 / 1.2785)}
  .dtile--lead{grid-column:span 2;grid-row:span 2}
  /* 12 tiles with one 2x2 lead is 15 cells: odd, so one hole at 2 columns.
     A second 2x2 at the end closes it. */
  .dtile:last-child{grid-column:span 2;grid-row:span 2}
}

/* ---- the viewer eases in and out instead of snapping ---- */
.lb{border-radius:14px;opacity:0;transform:translateY(10px) scale(.985);
  transition:opacity .3s var(--ease),transform .3s var(--ease),overlay .3s allow-discrete,display .3s allow-discrete}
.lb[open]{opacity:1;transform:none}
@starting-style{.lb[open]{opacity:0;transform:translateY(10px) scale(.985)}}
.lb::backdrop{background:rgba(5,6,8,0);backdrop-filter:none;
  transition:background-color .3s,overlay .3s allow-discrete,display .3s allow-discrete}
.lb[open]::backdrop{background:rgba(5,6,8,.9)}
@starting-style{.lb[open]::backdrop{background:rgba(5,6,8,0)}}
.lb-fig{border-radius:14px;overflow:hidden}
.lb-fig img{opacity:0;transition:opacity .35s ease}
.lb-fig img.ld{opacity:1}
.lb-btn{border-radius:10px}
@media (prefers-reduced-motion:reduce){
  .tile--img img,.tl,.lb,.lb::backdrop,.lb-fig img{transition:none}
  .tile--img:hover img{transform:none}
}

/* the handle is short now that it no longer cycles: let it be the headline */
.cycler{font-size:clamp(30px,10.5cqw,92px)}
/* text tiles size their type from THEIR OWN width: a 2-column tile and a
   4-column one are different measures, and a chapter-wide cqw broke
   "TRAVELER" across lines in the narrow tile */
.tile--text{container-type:inline-size;padding:clamp(12px,8cqw,26px)}
.tt-num{font-size:clamp(34px,30cqw,104px)}
.tile--text h3{font-size:clamp(15px,11.5cqw,40px)}
.tt-line{font-size:clamp(10.5px,5.4cqw,13px)}
.tt-quote{font-size:clamp(15px,6.4cqw,32px)}
.t-eptext .tt-line{font-size:clamp(11px,6cqw,15px)}
.cycler{font-size:clamp(26px,9cqw,92px)}
@media (max-width:719px){.t-phead{padding:10px}.t-phead .tt-num{font-size:30cqw}.t-phead h3{font-size:12cqw}.t-phead .tt-line{font-size:clamp(10px,5.6cqw,12px)}}
/* Syne 800 capitals run ~1.1em a glyph: TRAVELER needs <=9cqw, IMAGINATION <=7.6cqw */
.tile--text h3{font-size:clamp(14px,8.6cqw,40px)}
.t-eptext h3{font-size:clamp(14px,7.4cqw,40px)}
@media (max-width:719px){.t-phead h3{font-size:8.6cqw}}
/* one corner language for the page: the social cards and archive links join the bento */
.scard{border-radius:14px;--g:clamp(8px,1.2vw,14px)}
.social-grid{gap:clamp(8px,1.2vw,14px)}
.link{border-radius:12px}
.sc-thumbs img{border-radius:8px}
.sc-big .sc-word{font-size:clamp(26px,2.9vw,42px);overflow-wrap:anywhere}
/* the archive sits on the same centred column as the rest of the page */
.links{padding-inline:max(var(--gut),calc((100% - 1080px) / 2))}

/* ============ WorkspaceHQ cartridge ============
   The founder's own product, presented as a game cartridge with Bit on the
   label. It wears WorkspaceHQ's arcade palette whatever the page theme (it is
   a different product's box), on its own dark ground, so contrast holds in
   light themes too. Still at rest — nothing here animates until hover/focus,
   so the page's no-endless-animation rule holds. */
@font-face{font-family:"Press Start 2P";src:url(../workspacehq/fonts/PressStart2P.woff2) format("woff2");font-display:swap}
.whq-cart{--g:#ffd23f;--g2:#ffe27a;position:relative;display:flex;align-items:center;gap:14px;max-width:440px;
  margin-top:22px;padding:14px 16px 24px 14px;color:#e8e6ff;text-decoration:none;background:linear-gradient(160deg,#1a1538,#100d24);
  border:2px solid #322a5e;outline:2px solid #050409;outline-offset:0;box-shadow:0 5px 0 #050409;
  transition:box-shadow .2s,border-color .2s,transform .2s cubic-bezier(.34,1.56,.64,1)}
.whq-cart::before{content:"";position:absolute;left:12px;right:12px;top:0;height:5px;
  background:repeating-linear-gradient(90deg,#322a5e 0 6px,transparent 6px 10px)}
/* the cartridge's cut corner, drawn rather than clipped so the hover ring shows */
.whq-cart::after{content:"";position:absolute;top:-2px;right:-2px;width:16px;height:16px;
  background:linear-gradient(225deg,var(--whq-page,#07060f) 0 50%,transparent 50%)}
.whq-bit{flex:none;width:54px;height:44px;display:grid;place-items:end center;
  background:repeating-linear-gradient(90deg,transparent 0 7px,rgba(90,78,168,.18) 7px 8px),#0c0a1e;border:2px solid #050409;padding:4px 0 3px}
.whq-bit svg{width:36px;height:27px;display:block;filter:drop-shadow(0 0 6px rgba(217,119,87,.45));transition:transform .18s cubic-bezier(.34,1.56,.64,1)}
.whq-eyes{transform-box:fill-box;transform-origin:center}
.whq-txt{display:grid;gap:5px;min-width:0}
.whq-kick{font-family:"Press Start 2P",monospace;font-size:7px;letter-spacing:1px;line-height:1.6;color:#00f0ff}
.whq-name{font-family:"Press Start 2P",monospace;font-weight:400;font-size:13px;letter-spacing:1px;line-height:1.3;color:#e8e6ff;white-space:nowrap}
.whq-name i{font-style:normal;color:var(--g);text-shadow:0 0 8px rgba(255,210,63,.6)}
.whq-name em{font-style:normal;font-size:9px;color:#ff2bd6}
.whq-sub{font-size:12px;line-height:1.35;color:#b3add9}
.whq-start{position:absolute;right:12px;bottom:7px;font-family:"Press Start 2P",monospace;font-size:6px;letter-spacing:1px;color:var(--g2);opacity:0}
.whq-xp{position:absolute;left:34px;top:4px;font-family:"Press Start 2P",monospace;font-size:7px;color:var(--g);text-shadow:0 0 8px rgba(255,210,63,.8);opacity:0;pointer-events:none}
.whq-cart:hover,.whq-cart:focus-visible{transform:translateY(-3px);border-color:var(--g);box-shadow:0 5px 0 #8a6200,0 0 28px -6px rgba(255,210,63,.75)}
.whq-cart:focus-visible{outline:2px solid var(--g);outline-offset:4px}
.whq-cart:hover .whq-bit svg,.whq-cart:focus-visible .whq-bit svg{animation:whq-hop .55s steps(4) 2}
.whq-cart:hover .whq-eyes,.whq-cart:focus-visible .whq-eyes{animation:whq-blink .9s steps(1) 1 .3s}
.whq-cart:hover .whq-start,.whq-cart:focus-visible .whq-start{animation:whq-press 1.1s steps(1) 3}
.whq-cart:hover .whq-xp,.whq-cart:focus-visible .whq-xp{animation:whq-xp .9s ease-out 1 forwards}
@keyframes whq-hop{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}
@keyframes whq-blink{0%,100%{transform:scaleY(1)}20%,40%{transform:scaleY(.1)}}
@keyframes whq-press{0%{opacity:1}50%{opacity:0}}
@keyframes whq-xp{0%{opacity:0;transform:translateY(4px)}25%{opacity:1}100%{opacity:0;transform:translateY(-22px)}}
html[dir="rtl"] .whq-cart::after{right:auto;left:-2px;background:linear-gradient(135deg,var(--whq-page,#07060f) 0 50%,transparent 50%)}
/* Press Start 2P has no Arabic glyphs */
html[dir="rtl"] .whq-kick{font-family:var(--font-ar-body,system-ui),sans-serif;font-size:12px;letter-spacing:0}
html[dir="rtl"] .whq-start{right:auto;left:12px}
@media (prefers-reduced-motion:reduce){.whq-cart,.whq-bit svg{transition:none}.whq-cart *{animation:none!important}.whq-cart:hover{transform:none}}
.link--whq{border-color:color-mix(in srgb,#ffd23f 45%,var(--line-2))}
.link--whq .badge{color:#ffd23f}
.whq-cart{--whq-page:var(--ink)}

/* breadcrumb: Numidea Labs / VOIDSPLUNKER.std */
.topbar .bc{display:flex;align-items:center;gap:10px;margin:0;padding:0;list-style:none;min-width:0}
.topbar .bc li{display:flex;align-items:center;gap:10px}
.topbar .bc li+li::before{content:"/";font-family:var(--mono);font-size:11px;opacity:.45}
.topbar .bc a{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;opacity:.6;transition:opacity .2s}
.topbar .bc a:hover,.topbar .bc a:focus-visible{opacity:1}
/* .6 of the ink lands at 4.4:1 on paper */
:root[data-theme="light"] .topbar .bc a{opacity:.72}
:root[data-theme="light"] .topbar .bc a:is(:hover,:focus-visible){opacity:1}

/* ============================= PRINT =============================
   Paper is white and browsers leave backgrounds out, so print takes the
   light theme's inks whatever the screen theme (the dark theme's #ece9dd text
   printed nearly white on white), shows every reveal block (only what had
   been scrolled past used to print), and lets the few labels that are light
   on their own dark ground keep that ground. */
@media print{
  :root,:root[data-theme]{--ink:#fff;--ink-2:#fff;--panel:#fff;
    --paper:#14160f;--paper-dim:#494c40;--faint:#63665a;--acc-text:#357000;
    --line:#cccabd;--line-2:#adab9c}
  .reveal-armed [data-reveal]{opacity:1!important;transform:none!important;transition:none!important}
  [data-depth],[data-parallax]{transform:none!important}
  .badge{color:var(--paper)!important}
  .whq-cart,.tl{-webkit-print-color-adjust:exact;print-color-adjust:exact}
  .tl{opacity:1!important;transform:none!important}   /* hover-only labels print */
  .theme-pill,.skip{display:none}
}

/* ===== r3/a: mobile audit ===== */
/* Safe-area insets. viewport-fit=cover, but only the hero was inset, and
   only under 860px: in landscape on a notched phone (~47px insets a side,
   emulated at 844x390) the poster tiles, the social cards, the archive and
   the footer ran under the notch, from x=34 to x=810 of 844. */
@supports (padding:max(0px)){
  .hero,.site-foot{padding-left:max(var(--gut),env(safe-area-inset-left));padding-right:max(var(--gut),env(safe-area-inset-right))}
  .coll,.design,.social,.links{padding-left:max(var(--gut),calc((100% - 1080px) / 2),env(safe-area-inset-left));
    padding-right:max(var(--gut),calc((100% - 1080px) / 2),env(safe-area-inset-right))}
}
/* The lightbox: 94vh is the LARGE viewport on iOS, taller than what shows
   while the toolbars are out, so the caption bar sat under them. */
@supports (height:1dvh){
  .lb,.lb-fig{max-height:94dvh}
  .lb-fig img{max-height:calc(94dvh - 72px)}
}
/* A social card's handle broke one letter from its end at 320 ("@stick_itt
   / y", "@br4vetr4ave / ler1"): it shared one row with the badge, the name
   and the arrow. The row may wrap, so the handle moves down whole. The arrow
   is pinned in the card corner, centred on the badge (44px) row, outside the
   wrapping row: in the row it was the item that wrapped at 700 and 960-1024px,
   alone on a second line, and made those cards 22px taller. */
.scard{position:relative}
.sc-top{flex-wrap:wrap;row-gap:4px;padding-inline-end:18px}
.sc-top .go{position:absolute;top:20px;inset-inline-end:20px;height:44px;display:grid;place-items:center;margin:0}
/* Tile labels on a 320-400px phone: a design tile is 138x108px there, and
   "Sandwich Insulating Panels Graphic Assets" ran five lines, taller than the
   tile, which clipped its first word; "ego disintegration" broke one letter
   from its end. A tighter label and 11.5px type keep every title whole. */
@media (max-width:400px){
  .tl{left:6px;bottom:6px;max-width:calc(100% - 12px);padding:6px 8px 7px}
  .tl b{font-size:11.5px}
}
