/* wenvar. — public site stylesheet
   The identity is proportion, not metaphor (docs/brand-wenvar.md):
   φ = 1.6180339887 sets the type scale (16 × φⁿ), the spacing scale
   (5 · 8 · 13 · 21 · 34 · 55 · 89 · 144), the layout splits (38.2 : 61.8)
   and the motion scale (130 · 210 · 340 · 550 ms). Colour tokens are the
   product's own; cyan is interaction and the chord, never decoration. */

@font-face{font-family:'Inter';font-style:normal;font-weight:100 900;font-display:swap;src:url('/fonts/inter.woff2') format('woff2')}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:300 700;font-display:swap;src:url('/fonts/space-grotesk.woff2') format('woff2')}

:root{
  /* colour — verbatim from docs/brand-wenvar.md */
  --canvas:#0B0D10; --surface:#14171C; --line:#242931; --line-strong:#363C46;
  --ink:#F1F3F5; --muted:#98A1AC; --dim:#838B95;
  --brand:#26B6CE; --brand-ink:#04222A;
  --ok:#43B96B; --warn:#E2A33C; --bad:#E5484D;

  /* type — 16 × φⁿ, half-integer steps */
  --t-meta:12.573px;   /* n = −0.5, the floor */
  --t-body:16px;       /* n = 0  */
  --t-lead:20.362px;   /* n = 0.5 */
  --t-h4:25.888px;     /* n = 1  */
  --t-h3:32.944px;     /* n = 1.5 */
  --t-h2:41.888px;     /* n = 2  */
  --t-h1:67.802px;     /* n = 3  */

  /* spacing — Fibonacci */
  --s0:5px; --s1:8px; --s2:13px; --s3:21px; --s4:34px; --s5:55px; --s6:89px; --s7:144px;

  /* radii — same ladder */
  --r-sm:8px; --r-lg:13px;

  /* motion */
  --d-1:130ms; --d-2:210ms; --d-3:340ms; --d-4:550ms;
  --ease:cubic-bezier(0.22,1,0.36,1);
}

*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth;color-scheme:dark}
[id]{scroll-margin-top:89px}
body{
  background:var(--canvas); color:var(--ink);
  font-family:'Inter',system-ui,sans-serif;
  font-size:var(--t-body); line-height:1.6;
  -webkit-font-smoothing:antialiased;
  /* decorative absolutes (hero glow) may exceed the canvas; never let them
     hand the page a horizontal scrollbar */
  overflow-x:clip;
}
::selection{background:var(--brand);color:var(--brand-ink)}
h1,h2,h3,.wordmark{font-family:'Space Grotesk',sans-serif;font-weight:700;line-height:1.12;letter-spacing:-0.02em}
h1,h2{text-wrap:balance}
a{color:inherit;text-decoration:none}
img,svg{max-width:100%}
.container{max-width:1180px;margin:0 auto;padding:0 var(--s3)}
section{padding:var(--s7) 0}
:focus{outline:none}
:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:2px}

/* ---------- skip link ---------- */
.skip-link{
  position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--brand);color:var(--brand-ink);
  padding:var(--s2) var(--s3);border-radius:0 0 var(--r-sm) 0;font-weight:600;font-size:14px;
}
.skip-link:focus{left:0}

/* ---------- type roles ---------- */
.eyebrow{
  display:inline-flex;align-items:center;gap:var(--s1);
  font-size:var(--t-meta);font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--brand);margin-bottom:var(--s3);
}
/* the mini chord: the mark's own gesture, round caps, never touching anything */
.eyebrow::before{content:"";width:var(--s3);height:3px;border-radius:99px;background:var(--brand)}
.section-title{font-size:clamp(32.944px,3.6vw,var(--t-h2));margin-bottom:var(--s2)}
.section-sub{color:var(--muted);font-size:clamp(16px,1.35vw,17.5px);max-width:34em;margin-bottom:var(--s5);text-wrap:pretty}
.lead{color:var(--muted);font-size:clamp(17px,1.6vw,var(--t-lead));line-height:1.6;text-wrap:pretty}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s1);
  padding:var(--s2) 26px;border-radius:var(--r-sm);font-weight:600;font-size:15px;
  border:1px solid transparent;cursor:pointer;min-height:44px;
  font-family:'Inter',sans-serif;
  transition:filter var(--d-2) var(--ease),border-color var(--d-2) var(--ease),
             color var(--d-2) var(--ease),transform var(--d-1) var(--ease);
}
.btn:hover{transform:translateY(-1px)}
.btn-primary{background:var(--brand);color:var(--brand-ink)}
.btn-primary:hover{filter:brightness(1.1)}
.btn-ghost{border-color:var(--line-strong);color:var(--ink)}
.btn-ghost:hover{border-color:var(--brand);color:var(--brand)}
.btn-sm{padding:9px 18px;font-size:14px;min-height:38px}
.text-link{color:var(--muted);font-size:14px;text-decoration:underline;text-underline-offset:3px;transition:color var(--d-2) var(--ease)}
.text-link:hover{color:var(--ink)}

/* ---------- header ---------- */
header{
  position:sticky;top:0;z-index:50;
  background:color-mix(in srgb,var(--canvas) 86%,transparent);
  backdrop-filter:blur(13px);-webkit-backdrop-filter:blur(13px);
  border-bottom:1px solid var(--line);
}
.nav{display:flex;align-items:center;justify-content:space-between;height:68px}
.brand{display:flex;align-items:center;gap:0.42em;font-size:21px}
.brand .mark{width:1.15em;height:1.15em;flex:none;color:var(--ink)}
.brand .mark .chord{transition:transform var(--d-3) var(--ease)}
.brand:hover .mark .chord,.brand:focus-visible .mark .chord{transform:translateX(1.4px)}
.wordmark{display:inline-flex;align-items:baseline;letter-spacing:-0.01em;line-height:1}
/* the dot is drawn, never the font's period glyph (docs/brand-wenvar.md) */
.wordmark .dot{width:0.16em;height:0.16em;border-radius:50%;background:var(--brand);display:inline-block;margin-left:0.07em}
.nav-links{display:flex;gap:28px;font-size:14px;font-weight:500;color:var(--muted)}
.nav-links a{transition:color var(--d-2) var(--ease)}
.nav-links a:hover{color:var(--ink)}
.nav-links a.active{color:var(--ink);position:relative}
.nav-links a.active::after{content:"";position:absolute;left:0;right:0;bottom:-6px;height:2px;border-radius:99px;background:var(--brand)}
.nav-cta{display:flex;align-items:center;gap:var(--s3)}
.nav-signin{
  font-size:14px;font-weight:500;color:var(--muted);transition:color var(--d-2) var(--ease);
  display:inline-flex;align-items:center;min-height:44px;padding:0 var(--s1);
}
.nav-signin:hover{color:var(--ink)}
@media(max-width:980px){.nav-links{gap:18px;font-size:13px}}
/* two-row header on small screens: brand + Sign in share the first row,
   the full-width link row sits under them, 44px targets throughout */
@media(max-width:640px){
  .nav{flex-wrap:wrap;height:auto;padding:10px 0 0}
  .brand{height:40px;order:0}
  .nav-cta{margin-left:auto;order:1}
  .nav-cta .btn{display:none}
  .nav-links{
    order:2;flex-basis:100%;justify-content:space-between;gap:4px;
    font-size:14px;border-top:1px solid var(--line);margin-top:var(--s1);
  }
  .nav-links a{padding:12px 10px;min-height:44px;display:inline-flex;align-items:center}
  .nav-links a.active::after{bottom:6px}
}

/* ---------- hero ---------- */
/* overflow-x:clip so the glow's overhang never widens the mobile viewport */
.hero{position:relative;padding:var(--s7) 0 var(--s6);text-align:center;overflow-x:clip}
/* a whisper of a setout grid behind the hero, fading before it reaches copy */
.hero::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background-image:linear-gradient(var(--line) 1px,transparent 1px),
                   linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:55px 55px;opacity:.16;
  -webkit-mask-image:radial-gradient(75% 62% at 50% 24%,#000 0%,transparent 78%);
          mask-image:radial-gradient(75% 62% at 50% 24%,#000 0%,transparent 78%);
}
.hero>.container{position:relative}
.hero .eyebrow{justify-content:center}
.hero h1{
  font-size:clamp(53.297px,6vw,86.199px);line-height:1.05;letter-spacing:-0.02em;
  max-width:15em;margin:0 auto var(--s3);
}
.hero .lead{max-width:36em;margin:0 auto var(--s4)}
.hero-ctas{display:flex;gap:var(--s2);justify-content:center;flex-wrap:wrap}
.hero-ctas .btn{padding:16px 30px;font-size:15.5px;border-radius:11px}
.hero-note{margin-top:var(--s3);font-size:14px;color:var(--dim)}
.hero-note a{color:var(--muted);text-decoration:underline;text-underline-offset:3px}
.hero-note a:hover{color:var(--ink)}
.page-hero{padding:var(--s6) 0 var(--s5);text-align:left}
.page-hero h1{font-size:clamp(41.888px,4.8vw,var(--t-h1));max-width:14em;margin:0 0 var(--s3)}
.page-hero .lead{margin:0;max-width:36em}
@media(max-width:640px){.hero{padding:var(--s6) 0 var(--s5)}}

/* one-time entrance: the chord takes its reading (the product's own motif) */
@keyframes chord-in{from{transform:translateX(-2.2px);opacity:0}to{transform:none;opacity:1}}
.hero .eyebrow::before{animation:chord-in var(--d-4) var(--ease) both}

/* ---------- scroll reveal ----------
   Hiding is gated on html.js (set by a one-line inline script in each head)
   so content is never invisible when JavaScript is off. */
.reveal{transition:opacity var(--d-3) var(--ease),transform var(--d-3) var(--ease)}
html.js .reveal{opacity:0;transform:translateY(13px)}
html.js .reveal.in{opacity:1;transform:none}
.reveal[data-reveal-delay="1"]{transition-delay:var(--d-1)}
.reveal[data-reveal-delay="2"]{transition-delay:calc(var(--d-1)*2)}
.reveal[data-reveal-delay="3"]{transition-delay:calc(var(--d-1)*3)}
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{transition:none !important;animation:none !important}
  .reveal,html.js .reveal{opacity:1;transform:none}
  .btn:hover{transform:none !important}
}

/* ---------- the φ split ---------- */
.phi{display:grid;grid-template-columns:38.2fr 61.8fr;gap:var(--s5);align-items:center}
/* a table's min-content width must never widen the page */
.phi>*{min-width:0}
.phi.flip{grid-template-columns:61.8fr 38.2fr}
.phi.flip>.phi-copy{order:2}
.phi.flip>.phi-visual{order:1}
.phi-copy .section-sub{margin-bottom:var(--s3)}
.phi-copy p{color:var(--muted);font-size:15.5px;margin-bottom:var(--s2);text-wrap:pretty}
.phi-copy p b{color:var(--ink);font-weight:600}
/* the register showcase (product 03): the chapter title and its copy share
   one two-column head, then the register runs the full container width so
   the replica lays out near the product's own size instead of being zoomed
   to fit beside three paragraphs */
.showcase-head{
  display:grid;grid-template-columns:38.2fr 61.8fr;grid-template-rows:auto auto;
  gap:0 var(--s5);align-items:start;margin-bottom:var(--s4);
}
.showcase-head>*{min-width:0}
/* the number and eyebrow sit alone in the first row, as in every other
   chapter; the title and the copy share the second row, so the copy starts
   below the eyebrow line, level with the title */
.showcase-kicker{grid-column:1;grid-row:1}
.showcase-head .section-title{grid-column:1;grid-row:2;margin-bottom:0}
.showcase-copy{grid-column:2;grid-row:2;padding-top:4px}
.showcase-copy p{max-width:640px}
.showcase-copy p:last-child{margin-bottom:0}
@media(max-width:980px){
  .showcase-head{grid-template-columns:1fr;grid-template-rows:auto auto auto}
  .showcase-head .section-title{margin-bottom:var(--s2)}
  .showcase-copy{grid-column:1;grid-row:3;padding-top:0}
}
@media(max-width:980px){
  .phi,.phi.flip{grid-template-columns:1fr;gap:var(--s4)}
  .phi.flip>.phi-copy{order:1}
  .phi.flip>.phi-visual{order:2}
  .phi>.phi-visual{order:2}
}

/* ---------- cards & product depictions ---------- */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);}
/* two-layer lift + a 1px top highlight so mockups sit off the canvas */
.shadow{box-shadow:inset 0 1px 0 rgba(241,243,245,.05),0 2px 8px rgba(0,0,0,.35),0 34px 89px -34px rgba(0,0,0,.55)}

/* register window */
.mock-window{padding:0;overflow:hidden;font-size:12.5px}
.mock-titlebar{
  display:flex;align-items:center;gap:var(--s2);
  padding:10px var(--s3);border-bottom:1px solid var(--line);background:var(--surface);
}
.mock-titlebar .wordmark{font-size:13px}
.mock-titlebar .mock-project{color:var(--muted);font-size:11.5px;margin-left:auto;display:flex;align-items:center;gap:6px}
/* photo layers sit over the gradient; a missing file degrades to today's look */
.reg-thumb{
  width:44px;height:33px;border-radius:4px;border:1px solid var(--line-strong);display:block;
  background-color:#171b21;
  background-image:linear-gradient(135deg,#20242b 0%,#171b21 55%,#12151a 100%);
  background-size:cover;background-position:center;
}

/* ---------- .reg-app: the register, drawn at the product's own sizes ----------
   One replica used by all three register depictions. Everything inside is in
   the pixels the real app uses (web/app/ui.ts + register-table.tsx): 36px
   controls, 14px body, 12px meta, 11px plates, 24px chips, rounded 6 on
   controls and 8 on containers. Each instance then sets --rs and the block is
   scaled with CSS `zoom` — never `transform`, which is forbidden inside
   .lid-screen and would also blur the hairlines. Column widths are variables
   because the real register lets a person resize and remember them. */
.reg-app{
  zoom:var(--rs,.6);
  font-family:'Inter',system-ui,sans-serif;font-size:14px;line-height:1.45;
  color:var(--ink);background:var(--canvas);
  display:flex;flex-direction:column;min-height:0;
  --pad:24px;
  --c-sel:36px; --c-photo:136px; --c-taken:126px; --c-tags:164px; --c-loc:184px; --c-prov:196px;
}
.reg-app *{min-width:0}
/* band 1 — the nameplate */
.ra-plate{
  display:flex;align-items:center;gap:16px;height:28px;flex:none;
  padding:0 var(--pad);background:var(--surface);border-bottom:1px solid var(--line);
}
.ra-plate .wordmark{font-size:14px;line-height:1;color:var(--muted);display:inline-flex;align-items:center}
.ra-plate .wordmark .dot{width:.16em;height:.16em;margin-left:.07em}
.ra-mark{width:1.15em;height:1.15em;flex:none;margin-right:.42em}
/* band 2 — project, count and the view nav */
.ra-head{display:flex;align-items:center;flex-wrap:wrap;gap:8px 24px;padding:8px var(--pad);flex:none}
.ra-head-l{flex:1 1 224px;min-width:0}
.ra-proj{
  font-family:'Space Grotesk',sans-serif;font-weight:700;font-size:24px;line-height:1.25;
  letter-spacing:-0.02em;color:var(--ink);display:flex;align-items:baseline;gap:6px;
}
.ra-proj i{font-style:normal;font-size:14px;font-weight:400;color:var(--muted);letter-spacing:0}
.ra-sub{margin-top:2px;font-size:14px;line-height:1.45;color:var(--dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-variant-numeric:tabular-nums}
.ra-head-r{margin-left:auto;display:flex;align-items:center;gap:12px;flex:none}
.ra-nav{display:flex;align-items:stretch;height:36px;border:1px solid #666C76;border-radius:6px;background:var(--canvas)}
.ra-nav span{
  display:inline-flex;align-items:center;padding:0 12px;font-size:14px;color:var(--muted);white-space:nowrap;
}
.ra-nav span:first-child{border-radius:5px 0 0 5px}
.ra-nav span:last-child{border-radius:0 5px 5px 0}
.ra-nav span.on{background:var(--surface);color:var(--brand)}
.ra-nav span.adm{gap:6px;border-left:1px solid var(--line)}
.ra-nav span.adm i{font-style:normal;font-size:12px;color:#6B737D}
.ra-badge{
  width:32px;height:32px;border-radius:50%;border:1px solid #666C76;flex:none;
  display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;color:var(--muted);
}
/* the bordered container: filter band on top, table below */
.ra-box{
  border:1px solid var(--line);border-radius:8px;overflow:hidden;
  margin:0 var(--pad) 12px;display:flex;flex-direction:column;min-height:0;
}
.ra-filters{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;flex:none;
  padding:10px 12px;background:var(--line);border-bottom:1px solid var(--line-strong);
}
.ra-frame{
  display:flex;align-items:stretch;height:36px;overflow:hidden;flex:none;
  border:1px solid #666C76;border-radius:6px;background:var(--canvas);
}
.ra-frame.on{border-color:color-mix(in srgb,var(--brand) 60%,transparent)}
.ra-frame b{
  display:flex;align-items:center;padding:0 10px;background:var(--surface);border-right:1px solid var(--line);
  font-size:11px;font-weight:500;text-transform:uppercase;letter-spacing:.025em;color:var(--dim);white-space:nowrap;
}
.ra-frame.on>b{color:var(--brand)}
.ra-frame b.mid{border-left:1px solid var(--line)}
.ra-frame .v{display:flex;align-items:center;padding:0 8px;font-size:14px;color:var(--ink);white-space:nowrap}
.ra-frame .v.ph{color:var(--dim)}
.ra-frame .d{display:flex;align-items:center;gap:4px;padding:0 6px;font-size:14px;color:var(--ink)}
.ra-frame .d.ph{color:var(--dim)}
/* the native select caret, drawn so it matches the product's chevron */
.ra-cv{
  width:9px;height:6px;flex:none;background:currentColor;color:var(--muted);
  clip-path:polygon(0 0,50% 100%,100% 0,88% 0,50% 76%,12% 0);
}
.ra-words{flex:1 1 200px;min-width:160px}
.ra-words .v{flex:1}
.ra-tagf .v{width:128px}
.ra-person .v{width:160px}
.ra-trail{position:relative;display:flex;align-items:center;gap:4px;flex:none;border-left:1px solid var(--line);padding-left:8px;margin-left:4px}
.ra-quiet{display:inline-flex;align-items:center;height:36px;padding:0 8px;font-size:14px;color:var(--muted);white-space:nowrap}
.ra-btn{
  display:inline-flex;align-items:center;gap:6px;height:36px;padding:0 12px;border-radius:6px;
  border:1px solid #666C76;font-size:14px;color:var(--ink);white-space:nowrap;
}
.ra-btn i{font-style:normal;font-size:12px}
/* the table */
.ra-wrap{overflow:hidden;min-height:0}
.ra-table{width:100%;table-layout:fixed;border-collapse:collapse;font-size:14px}
.ra-table col.s{width:var(--c-sel)}
.ra-table col.p{width:var(--c-photo)}
.ra-table col.t{width:var(--c-taken)}
.ra-table col.g{width:var(--c-tags)}
.ra-table col.l{width:var(--c-loc)}
.ra-table col.v{width:var(--c-prov)}
.ra-table thead tr{background:color-mix(in srgb,var(--surface) 45%,transparent);border-bottom:1px solid var(--line)}
.ra-table th{
  position:relative;text-align:left;font-size:12px;font-weight:500;color:var(--muted);
  padding:10px 16px 10px 8px;white-space:nowrap;
}
.ra-table th:first-child,.ra-table td:first-child{padding-left:12px;padding-right:12px}
/* the resize rules that sit between the real column headers */
.ra-table th:not(:last-child)::after{
  content:"";position:absolute;top:8px;right:-1px;width:1px;height:24px;background:var(--line);
}
.ra-table th .srt{color:var(--brand);font-weight:400}
.ra-table td{padding:8px 16px 8px 8px;vertical-align:top;border-bottom:1px solid color-mix(in srgb,var(--line) 70%,transparent)}
.ra-table tbody tr:last-child td{border-bottom:0}
.ra-check{
  display:block;width:13px;height:13px;border-radius:3px;margin-top:3px;
  background:#2B3138;border:1px solid #4B525B;
}
.ra-thumb{
  display:block;width:100%;aspect-ratio:3/2;border-radius:4px;
  background-color:#171b21;background-size:cover;background-position:center;
}
.ra-taken .d{font-size:14px;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap;display:block}
.ra-taken .t{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap;display:block}
.ra-cap{font-size:14px;line-height:1.43;color:var(--ink);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.ra-sugg{
  display:inline-block;margin-left:6px;padding:0 6px;border-radius:4px;vertical-align:1px;
  border:1px solid var(--line-strong);font-size:11px;line-height:16px;color:var(--dim);white-space:nowrap;
}
.ra-tags{display:flex;flex-direction:column;gap:4px}
.ra-chips{display:flex;flex-wrap:wrap;gap:4px}
.ra-chip{
  display:inline-flex;align-items:center;gap:4px;height:24px;padding:0 6px;max-width:100%;
  border:1px solid var(--line-strong);border-radius:6px;background:var(--canvas);
  font-size:12px;color:var(--ink);white-space:nowrap;
}
.ra-chip i{font-style:normal;color:var(--dim)}
.ra-add{
  display:block;border:1px dashed var(--line);border-radius:4px;padding:2px 6px;
  font-size:11px;line-height:16px;color:var(--dim);
}
.ra-loc{font-size:12px;color:var(--muted)}
.ra-loc .a{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.ra-loc .m{display:flex;align-items:center;gap:6px;margin-top:4px;font-size:11px;color:var(--dim)}
.ra-loc .m u{text-decoration-color:#6B737D;text-underline-offset:2px}
.ra-loc .m span{font-variant-numeric:tabular-nums}
.ra-prov{font-size:12px;display:flex;align-items:center;flex-wrap:wrap;gap:6px}
.ra-prov .p{display:inline-flex;align-items:center;gap:6px;color:var(--ok);white-space:nowrap}
.ra-prov .p i{width:6px;height:6px;border-radius:50%;background:var(--ok);flex:none}
.ra-prov .who i{color:var(--dim);font-style:normal}
/* the column picker, open on the product page: the product's own panel */
.ra-colpop{
  position:absolute;z-index:4;right:0;top:calc(100% + 8px);width:192px;padding:6px;
  background:var(--surface);border:1px solid var(--line);border-radius:8px;
  box-shadow:0 21px 55px -21px rgba(0,0,0,.75);font-size:12px;
}
.ra-colpop label{display:flex;align-items:center;gap:8px;padding:4px 4px;color:var(--ink);border-radius:4px}
.ra-colpop label i{
  width:13px;height:13px;border-radius:3px;flex:none;background:#2B3138;border:1px solid #4B525B;
  display:inline-flex;align-items:center;justify-content:center;
}
.ra-colpop label.on i{background:var(--brand);border-color:var(--brand)}
.ra-colpop label.on i::after{content:"";width:6px;height:3px;border-left:1.5px solid var(--brand-ink);border-bottom:1.5px solid var(--brand-ink);transform:rotate(-45deg) translateY(-1px)}
.ra-colpop .rs{display:block;margin-top:4px;padding:6px 4px;color:var(--ink)}
/* a person has switched Location off in the column picker, so the column is
   gone and the widths the rest of the table gets are wider */
.ra-nocols{--c-photo:160px;--c-tags:200px;--c-prov:210px}
/* instance scales. Each container gets the largest zoom at which the six
   columns still fit: the hero screen is a small object, so its copy of the
   register is scaled down further than the two in-page ones. */
/* Instance scale. Every band picks the largest zoom at which the replica
   still lays out around 1150 to 1350 of its own pixels, which is the width
   the six columns were designed for; below that the caption column starts
   to crush. Both selectors are named in every band because the hero copy is
   inside a .mock-window as well as inside .lid-screen. */
.mock-window .reg-app{--rs:.56}
.lid-screen .reg-app{--rs:.63}
@media(max-width:1179px){
  .mock-window .reg-app{--rs:.52}
  .lid-screen .reg-app{--rs:.63}
}
@media(max-width:1079px){
  .mock-window .reg-app{--rs:.47}
  .lid-screen .reg-app{--rs:.63}
}
/* below about 1021 the laptop stops being held at its widest and the screen
   narrows with the viewport, so the register on it is scaled down again */
@media(max-width:1021px){
  .lid-screen .reg-app{--rs:.58}
}
@media(max-width:980px){
  .mock-window .reg-app,.lid-screen .reg-app{--rs:.69}
}
@media(max-width:860px){
  .mock-window .reg-app,.lid-screen .reg-app{--rs:.63}
}
@media(max-width:740px){
  .mock-window .reg-app,.lid-screen .reg-app{--rs:.52}
}
@media(max-width:640px){
  /* Location and Provenance switched off: a hidden-columns state the real
     register supports, rather than shrinking the type past reading size */
  .reg-app{--pad:16px;--c-photo:130px;--c-taken:120px;--c-tags:150px}
  .mock-window .reg-app,.lid-screen .reg-app{--rs:.69}
  .ra-table col.l,.ra-table col.v{width:0}
  .ra-table th:nth-child(6),.ra-table th:nth-child(7),
  .ra-table td:nth-child(6),.ra-table td:nth-child(7){display:none}
  .ra-nav span:nth-child(3),.ra-nav span:nth-child(4),.ra-nav span:nth-child(5){display:none}
  .ra-trail{border-left:0;padding-left:0;margin-left:0}
  /* an open menu would cover most of a phone-width table */
  .ra-colpop{display:none}
}
@media(max-width:560px){
  .mock-window .reg-app,.lid-screen .reg-app{--rs:.55}
}
@media(max-width:460px){
  .mock-window .reg-app,.lid-screen .reg-app{--rs:.44}
}
/* the full-width showcase runs near 1:1 (container 1138px wide at its
   widest, the replica 1211 of its own px); below 980 the shared rules above
   already treat every in-page register as full width */
@media(min-width:980px){
  .showcase-visual .reg-app{--rs:.94}
}
@media(min-width:980px) and (max-width:1221px){
  .showcase-visual .reg-app{--rs:.86}
}
@media(min-width:980px) and (max-width:1079px){
  .showcase-visual .reg-app{--rs:.78}
}

/* the burn lays no bar and no gradient over the photograph, only a dark halo
   behind the letters; the mock keeps the faintest wash so the stamp survives
   a bright sky */
.stamp::before{
  content:"";position:absolute;inset:0 0 auto;height:42%;pointer-events:none;
  background:linear-gradient(180deg,rgba(7,9,12,.4) 0%,rgba(7,9,12,.18) 55%,rgba(7,9,12,0) 100%);
}
/* the camera screen itself draws no scrim; the mock keeps a faint one only
   so the stamp preview stays readable over any viewfinder photograph */
.phone-screen::before{
  content:"";position:absolute;inset:0 0 auto;height:36%;pointer-events:none;z-index:0;
  background:linear-gradient(180deg,rgba(7,9,12,.55) 0%,rgba(7,9,12,.34) 45%,rgba(7,9,12,.14) 75%,rgba(7,9,12,0) 100%);
}
/* the stamp panel — mirrors the burn: map square left, time and place right */
.stamp{
  position:relative;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line);
  background:
    radial-gradient(120% 90% at 20% 0%,#232830 0%,transparent 60%),
    radial-gradient(90% 70% at 85% 100%,#12161c 0%,transparent 55%),
    linear-gradient(160deg,#1d2229 0%,#14181e 45%,#0e1116 100%);
  aspect-ratio:3/2;
}
/* the quiet suggestion of a photograph behind the stamp: a slab edge and
   formwork verticals, well below legibility — texture, not illustration */
.stamp-scene{position:absolute;inset:0;width:100%;height:100%}
.stamp-row{position:absolute;inset:var(--s3) var(--s3) auto;display:flex;justify-content:space-between;align-items:flex-start;gap:var(--s3)}
.stamp-map{width:96px}
/* the tile is the app's own MapKit snapshot, drawn the way StampRenderer
   draws it: black 35% underneath, the map at 72%, hairline white 32%,
   and no pin — the app has never drawn one */
.stamp-map .tile{
  width:96px;height:68px;border-radius:9px;overflow:hidden;position:relative;
  border:1px solid rgba(241,243,245,.32);display:block;background:rgba(0,0,0,.35);
}
.stamp-map .tile img{display:block;width:100%;height:100%;object-fit:cover;opacity:.72}
/* attribution strip along the tile's bottom, burned only into the photo */
.stamp-map .tile .attrib{
  position:absolute;left:0;right:0;bottom:0;height:13px;
  display:flex;align-items:center;padding-left:4px;background:rgba(0,0,0,.5);
}
.stamp-map .tile .attrib .wordmark{font-size:7.5px;color:#fff;line-height:1}
.stamp-map .coords{
  display:block;margin-top:5px;font-family:ui-monospace,'SF Mono',Menlo,monospace;
  font-size:8px;letter-spacing:0;white-space:nowrap;
  color:rgba(241,243,245,.8);text-shadow:0 1px 2px rgba(0,0,0,.8);
}
.stamp-meta{text-align:right;text-shadow:0 1px 2px rgba(0,0,0,.95),0 0 7px rgba(0,0,0,.8)}
.stamp-meta .t{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:17px;font-weight:600;color:#fff;display:block;line-height:1.2}
.stamp-meta .d{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:12px;font-weight:500;color:rgba(255,255,255,.92);display:block}
.stamp-meta .a1{font-size:12px;color:rgba(255,255,255,.95);display:block;margin-top:2px}
.stamp-meta .a2{font-size:10.5px;color:rgba(255,255,255,.8);display:block}
.stamp-meta .fix{
  display:inline-flex;align-items:center;gap:4px;margin-top:6px;
  font-size:9.5px;font-weight:500;color:var(--ok);
}
.stamp-meta .fix svg{width:8px;height:8px;flex:none;filter:drop-shadow(0 1px 2px rgba(0,0,0,.85))}
.stamp-meta .proj{display:block;margin-top:4px;font-size:10.5px;font-weight:600;color:var(--brand)}

/* phone (capture) — a replica of the camera screen, in the app's own order:
   iOS status bar, sync badge and the five glass buttons, the live stamp
   preview, the viewfinder, the zoom cluster, the shutter bar. The mock is
   about 0.72 of a real iPhone's width, so every measurement below is the
   app's own pt value scaled down with it. */
.phone{
  width:min(300px,78vw);border-radius:34px;border:1px solid var(--line-strong);
  background:#0a0c0f;padding:10px;box-shadow:0 34px 89px -34px rgba(0,0,0,.65);
}
.phone-screen{border-radius:26px;overflow:hidden;position:relative;aspect-ratio:9/19.5;
  display:flex;flex-direction:column;
  background:
    radial-gradient(130% 80% at 15% 5%,#272d36 0%,transparent 55%),
    radial-gradient(100% 70% at 90% 95%,#10141a 0%,transparent 60%),
    linear-gradient(165deg,#1e242c 0%,#151a21 50%,#0d1015 100%);
}
/* the camera preview is full-bleed under every control, as it is in the app */
.phone-screen>*{position:relative;z-index:1}

/* iOS status bar */
.ios-bar{
  display:flex;align-items:center;justify-content:space-between;
  height:33px;padding:0 15px 0 17px;color:#fff;flex:none;
}
.ios-time{
  display:inline-flex;align-items:center;gap:3px;
  font-size:11px;font-weight:700;letter-spacing:.01em;
  text-shadow:0 1px 2px rgba(0,0,0,.7);
}
.ios-time .ic-loc{width:7px;height:7px}
/* Laid out, never transformed: a transform put the pill on its own
   compositor layer, resampled against the bar on every scroll frame, and it
   read as a pill that swells and drifts. Centred by margins it is painted
   with the bar, at a whole pixel (the snap below), and cannot move
   relative to it. */
.ios-island{
  position:absolute;left:0;right:0;top:5px;margin:0 auto;
  width:84px;height:25px;border-radius:99px;background:#000;
}
.ios-stat{display:inline-flex;align-items:center;gap:4px;filter:drop-shadow(0 1px 2px rgba(0,0,0,.7))}
.ios-stat .ic{fill:#fff}
.ios-stat .ic-sig{width:13px;height:8.5px}
/* Cellular, not wifi: a site phone is on 5G. */
.ios-stat .ios-net{font-size:8px;font-weight:700;letter-spacing:-.2px;line-height:1;color:#fff}
.ios-stat .ic-bat{width:19px;height:8.5px}

/* top control bar: sync badge left, five 36 pt glass buttons right */
.cam-top{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 11px 0;flex:none}
.cam-sync{
  display:inline-flex;align-items:center;gap:4px;flex:none;
  padding:5px 8px;border-radius:99px;background:rgba(0,0,0,.42);
  font-size:9.5px;font-weight:500;color:var(--ok);
}
.cam-sync .ic{width:10px;height:10px;flex:none}
.cam-tools{display:inline-flex;align-items:center;gap:6px}
.cam-tools .gb{
  width:26px;height:26px;border-radius:50%;flex:none;color:#fff;
  display:inline-flex;align-items:center;justify-content:center;
  background:rgba(0,0,0,.42);border:1px solid rgba(255,255,255,.12);
}
.cam-tools .gb .ic{width:12px;height:12px}
/* tag-after-capture is on by default, so the tag button is the active one */
.cam-tools .gb.on{color:var(--brand);border-color:color-mix(in srgb,var(--brand) 70%,transparent)}

/* the live stamp preview, 14 pt in from each side */
.phone .stamp-row{position:static;padding:5px 11px 0;gap:9px;flex:none}
.phone .stamp-map{width:74px}
.phone .stamp-map .tile{width:74px;height:52px;border-radius:7px}
.phone .stamp-map .coords{font-size:7px;margin-top:4px;letter-spacing:0;white-space:nowrap}
.phone .stamp-meta .t{font-size:14px}
.phone .stamp-meta .d{font-size:10px}
.phone .stamp-meta .a1{font-size:10px}
.phone .stamp-meta .a2{font-size:8.8px}
.phone .stamp-meta .fix{font-size:8.5px;margin-top:5px}
.phone .stamp-meta .fix svg{width:7px;height:7px}
.phone .stamp-meta .proj{font-size:9px}
.cam-gap{flex:1 1 auto;min-height:13px}

/* zoom presets and the log-scale slider */
.cam-zoom{display:flex;flex-direction:column;align-items:center;gap:7px;padding-bottom:11px;flex:none}
.phone-zoom{
  display:inline-flex;gap:2px;padding:2px;border-radius:99px;background:rgba(0,0,0,.35);
}
.phone-zoom span{
  min-width:24px;height:20px;border-radius:99px;display:inline-flex;align-items:center;justify-content:center;
  font-size:8px;font-weight:700;color:rgba(255,255,255,.9);font-variant-numeric:tabular-nums;
}
.phone-zoom .sel{background:rgba(0,0,0,.55);color:var(--brand);font-size:8.5px}
.zoom-slider{position:relative;display:block;width:167px;height:19px;flex:none}
.zoom-slider::before,.zoom-slider .zs-fill{
  content:"";position:absolute;top:50%;height:3px;margin-top:-1.5px;border-radius:99px;
}
.zoom-slider::before{left:0;right:0;background:rgba(255,255,255,.22)}
.zoom-slider .zs-fill{left:0;width:22%;background:var(--brand)}
.zoom-slider .zs-thumb{
  position:absolute;left:22%;top:50%;width:13px;height:13px;margin:-6.5px 0 0 -6.5px;
  border-radius:50%;background:#fff;border:1.5px solid var(--brand);
  box-shadow:0 1px 3px rgba(0,0,0,.5);
}

/* bottom bar: last photo, shutter, the more menu */
.cam-bottom{display:flex;align-items:center;justify-content:space-between;padding:0 16px 18px;flex:none}
.cam-last{
  width:38px;height:38px;border-radius:6px;flex:none;border:1px solid rgba(255,255,255,.4);
  background-color:#171b21;background-size:cover;background-position:center;
}
.cam-more{width:38px;display:inline-flex;justify-content:flex-end;color:rgba(255,255,255,.85)}
.cam-more .ic{width:19px;height:19px}
.phone-shutter{
  width:54px;height:54px;border-radius:50%;border:3.2px solid #fff;flex:none;
  display:flex;align-items:center;justify-content:center;
}
.phone-shutter::after{content:"";width:41px;height:41px;border-radius:50%;background:#fff}
.badge{
  display:inline-flex;align-items:center;gap:6px;
  padding:7px 11px;border-radius:99px;background:rgba(0,0,0,.42);
  font-size:10.5px;font-weight:500;
}
.badge.pending{color:var(--warn)}
.badge.synced{color:var(--ok)}
.badge i{width:5px;height:5px;border-radius:50%;background:currentColor}

/* hero composition: register window with the phone overlapping.
   .par-* wrappers exist so pointer parallax transforms never fight the
   .reveal entrance transform on the mockups themselves. */
.hero-visual{position:relative;max-width:980px;margin:var(--s6) auto 0;text-align:left}
.hero-visual::before{
  content:"";position:absolute;inset:-13% -21%;pointer-events:none;z-index:0;
  background:radial-gradient(52% 55% at 55% 42%,color-mix(in srgb,var(--brand) 8%,transparent) 0%,transparent 72%);
}
.hero-visual .par-win{position:relative;z-index:1}
/* the window never extends under the phone: side by side with a hairline
   gap, the phone overlapping only vertically for depth */
/* pre-zoom units (the laptop renders at zoom .8 on desktop): 465px here is
   the phone (300) plus a 72px clearance, divided by .8. The clearance is
   sized so the lid's near edge, which projects a little wider as it folds
   toward the viewer, never reaches the phone at any angle (growth ≈ 2%). */
.hero-visual .laptop{margin-left:auto;max-width:min(820px,calc(100% - 465px))}
/* the phone is a full 9:19.5 screen now, so it hangs 55px below the window
   to keep clear of the hero note above it */
/* Parallax and the pixel snap both land here as variables (site.js). The
   snap corrects the phone's page position to a whole pixel on both axes:
   the laptop's zoom leaves the container's height fractional and centring
   can leave its left edge on a half pixel, and either blurs the Dynamic
   Island's edges. */
.hero-visual .par-phone{
  position:absolute;left:0;bottom:-55px;z-index:2;
  transform:translate(calc(var(--px,0px) + var(--snap-x,0px)),calc(var(--py,0px) + var(--snap-y,0px)));
}
/* Neither wrapper is promoted to its own compositor layer (no will-change,
   no 3D transform): a promoted layer is rasterised once and then resampled
   at whatever fraction of a pixel the scroll leaves it on, which is what
   made the phone shimmer. Painted with the page, it scrolls pixel-locked.
   The lid keeps its own layer; it is the one thing that really moves. */
.hero-visual .par-win{transform:translate(var(--px,0px),var(--py,0px))}
@media(max-width:980px){
  .hero-visual .par-phone{position:static;margin:var(--s4) auto 0;display:flex;justify-content:center}
  .hero-visual .laptop{margin:0 auto;max-width:820px}
  .laptop-base{margin:0}
}

/* ---------- the laptop ----------
   A 14-inch Space Black MacBook Pro as one solid CSS box model. Every face
   exists all the time and is lit by a fixed gradient; the only thing that
   changes with scroll is the hinge angle (--lid, driven by site.js wireLid,
   desktop only, reduced motion leaves it open). No face fades in or out:
   faces appear and disappear only because the geometry turns them toward or
   away from the camera, so nothing pops.

   Dimensions are in pre-zoom px (.laptop renders at zoom .8 on desktop):
     --lt  lid thickness       --bt  base thickness
     --lid-h  the lid's height, measured by site.js, so the deck is exactly
              as deep as the lid is tall and a closed lid covers it edge to edge

   Axes: the hinge is the lid's bottom edge. rotateX(negative) folds the lid
   down toward the viewer; the deck lies flat from the hinge toward the
   viewer; the front face hangs from the deck's near edge. The deck plane
   sits 2px below the hinge line so the closed lid rests just above it and
   never fights it for the same pixels.

   Faces, hinge side outward: the bezel (.laptop-lid itself) carrying the
   screen plane (.lid-screen, with the notch, the glass sheen and the dimming
   overlay), the lid's top edge (.lid-top) and side edges (.lid-side), the
   shell (.lid-back); then the deck (.laptop-deck: hinge, speaker grilles,
   keyboard well, trackpad), its side faces (.deck-side), the front face
   (.laptop-base) and the desk shadow (.deck-shadow) beneath it all.
   The fold stops at 89.9°, not 90°: see wireLid in site.js. */
/* A long lens: 24000px of perspective from a camera 7468px above the hinge
   line. The deck's near edge is 504px closer to the camera than the hinge,
   so it draws 2% wider, not the 14% a 4200px lens gave, and lid and base read
   as one width, as on a product photograph. The height of the camera sets
   how deep the deck looks (about a third of the lid); both are px on
   purpose, so the ratio holds at every laptop size. */
.laptop{perspective:24000px;perspective-origin:50% -7468px;--lt:10px;--bt:16px;--gap:2px}
.laptop-3d{position:relative;transform-style:preserve-3d;padding-bottom:150px}

/* the lid: this element is the bezel face; its children are the other faces */
.laptop-lid{
  position:relative;transform-style:preserve-3d;
  transform-origin:50% 100%;transform:rotateX(var(--lid,0deg));
  will-change:transform;backface-visibility:hidden;-webkit-backface-visibility:hidden;
  padding:11px 11px 14px;
  border-radius:18px 18px 6px 6px;
  outline:1px solid transparent;
  background:linear-gradient(180deg,#1c1c1f 0%,#121214 40%,#0d0d0f 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.07),
    inset 1px 0 0 rgba(255,255,255,.03),inset -1px 0 0 rgba(255,255,255,.03),
    inset 0 -1px 0 rgba(0,0,0,.7);
}
/* the outer shell: the same slab seen from behind, one thickness back.
   Its local top is the lid's top edge, which faces the viewer when closed. */
.lid-back{
  position:absolute;inset:0;border-radius:18px 18px 6px 6px;
  outline:1px solid transparent;
  transform:translateZ(calc(var(--lt) * -1)) rotateY(180deg);
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  background:
    radial-gradient(90% 60% at 50% 0%,rgba(255,255,255,.09) 0%,transparent 60%),
    linear-gradient(112deg,transparent 28%,rgba(255,255,255,.028) 44%,rgba(255,255,255,.05) 50%,rgba(255,255,255,.028) 56%,transparent 72%),
    linear-gradient(180deg,#2e2e33 0%,#26262a 45%,#1f1f23 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14),inset 0 -1px 0 rgba(0,0,0,.45);
}
/* the top edge: a strip as thick as the lid, standing back from the bezel
   plane to the shell plane, faded into the rounded corners at each end */
.lid-top{
  position:absolute;left:0;right:0;top:calc(var(--lt) * -1);height:var(--lt);
  transform-origin:50% 100%;transform:rotateX(90deg);
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  background:linear-gradient(180deg,#4a4a52 0%,#36363c 55%,#2a2a2f 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22);
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 18px,#000 calc(100% - 18px),transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 18px,#000 calc(100% - 18px),transparent 100%);
}
/* the side edges: only ever seen as a sliver, but a solid needs them */
.lid-side{
  position:absolute;top:18px;bottom:6px;width:var(--lt);
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  background:linear-gradient(180deg,#2c2c31,#1e1e22);
}
.lid-side-l{left:calc(var(--lt) * -1);transform-origin:100% 50%;transform:rotateY(-90deg)}
.lid-side-r{right:calc(var(--lt) * -1);transform-origin:0 50%;transform:rotateY(90deg)}
/* the screen is ONE flattened plane inside the 3D lid (WebKit otherwise
   depth-sorts the table's own layer separately: rows vanish, escape the
   dimming, or show from behind). It carries the notch and the dimming. */
.lid-screen{
  position:relative;transform:translateZ(0.5px);transform-style:flat;
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  border-radius:7px 7px 2px 2px;
}
.lid-screen::before{
  content:"";position:absolute;left:50%;top:0;transform:translateX(-50%);z-index:3;
  width:12%;height:11px;border-radius:0 0 8px 8px;background:#0d0d0f;
}
/* glass: a faint sheen from the top left, the one thing a real panel adds
   to what is on it. Far too light to touch legibility. */
.lid-glass{
  position:absolute;inset:0;z-index:2;pointer-events:none;
  border-radius:7px 7px 2px 2px;
  background:linear-gradient(100deg,rgba(255,255,255,.045) 0%,rgba(255,255,255,.014) 24%,transparent 42%);
}
.laptop-lid .mock-window{border-radius:7px 7px 2px 2px;border-color:#0a0a0b;box-shadow:none;backface-visibility:hidden;-webkit-backface-visibility:hidden}
.laptop-lid .mock-chrome{padding-top:14px}
/* the panel darkens as it turns away from the viewer (site.js drives --dim
   from 0 at 10° to 1 at 70°), so the last stretch of the fold shows black
   glass with a faint reflection rather than content seen edge-on */
.lid-screen::after{
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  border-radius:7px 7px 2px 2px;
  background:linear-gradient(165deg,#111317 0%,#08090b 55%,#0a0b0e 100%);
  opacity:var(--dim,0);
}
@media(min-width:981px){
  .laptop{zoom:.8}
  .laptop-lid .mock-window{aspect-ratio:3024/1964;display:flex;flex-direction:column;overflow:hidden}
  .laptop-lid .reg-app{flex:1;min-height:0}
  .laptop-lid .ra-wrap{flex:1;min-height:0}
}

/* the body. The deck lies flat from the hinge toward the viewer, exactly as
   deep as the lid is tall; the front face hangs from its near edge; the
   sides close the box; a soft shadow lies on the desk beneath it. */
.laptop-body{position:relative;height:0;transform-style:preserve-3d;transform:translateY(var(--gap))}
.laptop-deck{
  /* height from the measured lid (site.js); without it the ratio stands in.
     width is explicit, never left/right: with a definite height and an
     aspect-ratio, Chrome sizes an inset-stretched box from the ratio
     instead, which made the deck 19px narrower than the lid and flush
     left, so the lid overhung the base on the right. */
  position:absolute;left:0;width:100%;top:0;height:var(--lid-h);aspect-ratio:1/0.68;
  transform-origin:50% 0;transform:rotateX(90deg);transform-style:preserve-3d;
  border-radius:6px 6px 18px 18px;
  outline:1px solid transparent;backface-visibility:hidden;-webkit-backface-visibility:hidden;
  background:
    radial-gradient(70% 55% at 50% 110%,rgba(255,255,255,.05) 0%,transparent 70%),
    linear-gradient(180deg,#141416 0%,#1b1b1e 45%,#212125 100%);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.045);
}
/* a lid coming down shades the deck (site.js drives --shade, 0 at 15° to
   .65 at 85°): smooth and physical, never a switch */
.laptop-deck::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:linear-gradient(180deg,rgba(0,0,0,.95) 0%,rgba(0,0,0,.75) 50%,rgba(0,0,0,.55) 100%);
  opacity:var(--shade,0);
}
.laptop-deck .hinge{
  position:absolute;left:8%;right:8%;top:0;height:6px;border-radius:0 0 4px 4px;
  background:linear-gradient(180deg,#0a0a0c,#1a1a1d);
  box-shadow:0 1px 0 rgba(255,255,255,.04);
}
/* the keyboard: a 14-inch MacBook Pro layout drawn key by key as inline SVG
   in index.html (generated, 6 rows on a 14.5-unit pitch, inverted-T arrows,
   full-height function row). Legends are real text in the page's Inter so
   they stay crisp under the 3D camera; symbols are paths because the woff2
   subsets carry no ⌘ ⌥ ⌃ ⇧. Width only: the SVG's own ratio sets the
   height, so the caps stay square whatever the deck measures. Proportions
   are the machine's: the keyboard spans 86% of the deck with a speaker
   grille either side, the trackpad 41% of its width below. */
.laptop-deck .keys{
  position:absolute;left:6.9%;width:86.2%;top:4.5%;display:block;overflow:visible;
  border-radius:5px;background:#08080a;font-family:'Inter',system-ui,sans-serif;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.7),0 0 0 1px rgba(255,255,255,.035),inset 0 2px 4px rgba(0,0,0,.55);
}
.kb-well{fill:#08080a}
.kb-cap{fill:url(#kb-cap);stroke:rgba(255,255,255,.06);stroke-width:.5}
.kb-t{fill:#d6d7db;fill-opacity:.62;font-weight:500;text-anchor:middle;dominant-baseline:central}
.kb-l{font-size:6px}
.kb-s{font-size:4.3px}
.kb-n{font-size:5.4px}
.kb-w{font-size:3.5px}
.kb-i{fill:none;stroke:#d6d7db;stroke-opacity:.6;stroke-width:.7;stroke-linecap:round;stroke-linejoin:round}
.kb-if{fill:#d6d7db;fill-opacity:.6}
.kb-faint{stroke-opacity:.25}
/* speaker grilles either side of the keys: matte, a shade darker, recessed,
   as deep as the keyboard (the ratio is the keyboard's height over 4.4% of
   the deck's width) */
.laptop-deck .grille{
  position:absolute;top:4.5%;width:4.4%;aspect-ratio:44/361;border-radius:3px;
  background:
    radial-gradient(circle,rgba(0,0,0,.6) 0 .55px,transparent .95px) 0 0/3.2px 3.2px,
    rgba(0,0,0,.2);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.5),inset 0 0 0 1px rgba(255,255,255,.02);
}
.laptop-deck .grille-l{left:1.2%}
.laptop-deck .grille-r{right:1.2%}
.laptop-deck .pad{
  position:absolute;left:29.25%;width:41.5%;top:61.5%;height:34%;border-radius:6px;
  background:linear-gradient(180deg,#1e1e22,#1a1a1d);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.07),inset 0 1px 0 rgba(255,255,255,.03),0 0 0 1px rgba(0,0,0,.35);
}
/* the sides of the base, standing down from the deck's long edges */
.laptop-deck .deck-side{
  position:absolute;top:6px;bottom:18px;width:var(--bt);
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  background:linear-gradient(180deg,#1e1e22,#0f0f11);
}
.laptop-deck .deck-side-l{left:0;transform-origin:0 50%;transform:rotateY(-90deg)}
.laptop-deck .deck-side-r{right:0;transform-origin:100% 50%;transform:rotateY(90deg)}
/* the front face with the finger lip */
.laptop-base{
  position:absolute;left:0;right:0;top:100%;height:var(--bt);
  transform-origin:50% 0;transform:rotateX(-90deg);
  border-radius:0 0 9px 9px;
  outline:1px solid transparent;backface-visibility:hidden;-webkit-backface-visibility:hidden;
  background:linear-gradient(180deg,#2a2a2f 0%,#1a1a1d 30%,#131316 70%,#0b0b0c 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12);
}
.laptop-base i{
  position:absolute;left:50%;top:0;transform:translateX(-50%);
  width:15%;height:5px;border-radius:0 0 6px 6px;background:#08080a;
  box-shadow:inset 0 -1px 0 rgba(255,255,255,.05);
}
/* the desk shadow: a soft pool in the deck's own plane, just beneath it */
.laptop-deck .deck-shadow{
  position:absolute;left:-9%;right:-9%;top:-6%;bottom:-26%;
  transform:translateZ(calc(var(--bt) * -1 - 1px));
  border-radius:50%;
  background:radial-gradient(56% 52% at 50% 42%,rgba(0,0,0,.78) 0%,rgba(0,0,0,.42) 42%,transparent 74%);
}

/* ---------- map depiction ----------
   The product's map page is MapLibre GL over raster OpenStreetMap tiles
   (web/app/p/[id]/map/map-client.tsx), so both mocks are that screen: a real
   OSM composite for the ground, the register's own filter frames floating at
   the top left, MapLibre's navigation control at the top right, its compact
   attribution at the bottom right, and the readout bar at the bottom left.
   Because the ground is real OSM imagery, the attribution is a licence
   requirement, not decoration, and is drawn outside the scaled chrome so it
   stays legible at every width.

   --mz scales the chrome only: the mock stands for a wider window drawn
   smaller, so the app's parts keep their real proportions to each other while
   the pins stay at the pixel sizes the code sets. */
.map-frame{container-type:inline-size}
.map-mock{
  --mz:.5;
  position:relative;border-radius:var(--r-lg);overflow:hidden;
  border:1px solid var(--line);background:var(--canvas);
}
@container (min-width:400px){.map-mock{--mz:.56}}
@container (min-width:470px){.map-mock{--mz:.62}}
@container (min-width:560px){.map-mock{--mz:.67}}
@container (min-width:650px){.map-mock{--mz:.72}}
@container (min-width:860px){.map-mock{--mz:.78}}

.map-canvas{position:relative;aspect-ratio:640/400;overflow:hidden}
.map-mock.mm-wide .map-canvas{aspect-ratio:640/360}
/* a narrow window is a tall window: the map keeps room for its own chrome */
@container (max-width:600px){.map-canvas{aspect-ratio:4/3}}
@container (max-width:400px){.map-canvas,.map-mock.mm-wide .map-canvas{aspect-ratio:1/1}}

.map-tiles{
  position:absolute;inset:0;
  background:#E9E5DC url('/images/maps/osm-varsity-1280x800.jpg') center/cover no-repeat;
}
.map-mock.mm-wide .map-tiles{background-image:url('/images/maps/osm-varsity-1280x720.jpg')}

/* pins, at the sizes map-client.tsx sets: one record is a 14px circle with a
   2px #14171c ring; a group is min(30, 18 + count) px with the count in
   700 11px system-ui. Green holds a Wenvar capture, grey is imported only. */
.mp{
  position:absolute;z-index:1;transform:translate(-50%,-50%);
  width:14px;height:14px;border-radius:50%;
  border:2px solid #14171C;background:#43B96B;
}
.mp.mp-imp{background:#98A1AC}
.mp.mp-grp{
  width:30px;height:30px;
  display:flex;align-items:center;justify-content:center;
  color:#04222A;font:700 11px system-ui,-apple-system,sans-serif;
}
.mp.mp-grp.mp-4{width:22px;height:22px;font-size:10px}

/* the open group popup, as MapLibre draws it: white paper, system font, and
   the 61.8 : 38.2 row split the product uses. Sized as the product sizes it
   on a narrow window, and it passes UNDER the controls, as it really does. */
.map-pop{
  position:absolute;z-index:2;width:min(272px,44%);
  transform:translate(-50%,-100%);margin-top:-21px;
}
.map-pop-in{
  position:relative;background:#fff;border-radius:4px;padding:8px 8px 12px;
  box-shadow:0 2px 7px rgba(0,0,0,.3);
  font-family:system-ui,-apple-system,'Inter',sans-serif;color:#111;
}
.map-pop-x{position:absolute;right:4px;top:0;font-size:12px;line-height:1;color:#666}
.map-pop-body{
  max-height:min(176px,40cqw);overflow:hidden;
  -webkit-mask-image:linear-gradient(#000 74%,rgba(0,0,0,.1));
  mask-image:linear-gradient(#000 74%,rgba(0,0,0,.1));
}
.map-pop-h{font:600 11.5px system-ui,-apple-system,sans-serif;padding-bottom:4px}
.map-pop-r{display:flex;gap:8px;align-items:stretch;padding:7px 0;border-bottom:1px solid #eee}
.map-pop-r .t{
  width:61.8%;aspect-ratio:3/2;flex:none;border-radius:5px;
  background-color:#e5e5e5;background-size:cover;background-position:center;
}
.map-pop-r .b{min-width:0;flex:1}
.map-pop-r .m{display:block;font-size:9.5px;line-height:1.4;color:#666}
.map-pop-r .c{display:block;margin-top:3px;font-size:10.5px;line-height:1.4;color:#111}
.map-pop-tip{
  position:absolute;left:50%;bottom:-9px;transform:translateX(-50%);width:0;height:0;
  border-left:9px solid transparent;border-right:9px solid transparent;border-top:10px solid #fff;
}

/* MapLibre's compact attribution control, bottom right */
.map-attrib{
  position:absolute;z-index:4;right:0;bottom:0;
  display:flex;align-items:center;gap:5px;
  padding:2px 4px 2px 8px;border-radius:12px 0 0 0;
  background:rgba(255,255,255,.85);color:rgba(0,0,0,.78);
  font:9px/1.5 system-ui,-apple-system,sans-serif;white-space:nowrap;
}
.map-attrib i{
  width:12px;height:12px;border-radius:50%;background:rgba(0,0,0,.72);color:#fff;
  display:inline-flex;align-items:center;justify-content:center;
  font:600 8px/1 Georgia,serif;font-style:normal;
}

/* the app's chrome, scaled as one piece so its parts keep their proportions */
.map-chrome{position:absolute;inset:0;z-index:3;zoom:var(--mz)}

/* the filter row map-client.tsx floats at the top left: the register's own
   frames, wrapping when the map is narrow */
.map-ctrls{
  position:absolute;left:12px;top:12px;
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  width:max-content;max-width:calc(100% - 24px);
  padding:8px;border-radius:8px;border:1px solid var(--line);
  background:rgba(11,13,16,.9);
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
}
/* one filter wearing its own name: a label plate, then the field (app/ui.ts) */
.mfr{
  display:flex;align-items:stretch;height:36px;overflow:hidden;
  border:1px solid #666C76;border-radius:6px;background:var(--canvas);
}
.mfr.on{border-color:color-mix(in srgb,var(--brand) 60%,transparent)}
.mfr>b{
  display:flex;align-items:center;padding:0 10px;
  border-right:1px solid var(--line);background:var(--surface);
  font-size:11px;font-weight:500;letter-spacing:.04em;text-transform:uppercase;color:var(--dim);
}
.mfr>b.mid{border-left:1px solid var(--line)}
.mfr.on>b{color:var(--brand)}
/* a select that has given up its own edges, chevron and all */
.mfr .msel{display:flex;align-items:center;gap:5px;padding:0 6px;font-size:14px;color:var(--ink)}
.mfr .msel::after{
  content:"";width:6px;height:6px;margin-bottom:2px;
  border-right:1.3px solid var(--muted);border-bottom:1.3px solid var(--muted);
  transform:rotate(45deg);
}
.mfr .mval{display:flex;align-items:center;padding:0 8px;font-size:14px;color:var(--ink)}
.mfr .mval.ph{color:var(--dim)}
.map-clear{display:inline-flex;align-items:center;height:36px;padding:0 8px;font-size:14px;color:var(--muted)}

/* MapLibre's navigation control, top right */
.map-nav{
  position:absolute;right:10px;top:10px;width:29px;
  border-radius:4px;background:#fff;box-shadow:0 0 0 2px rgba(0,0,0,.1);overflow:hidden;
}
.map-nav .nb{display:block;height:29px;border-bottom:1px solid #ddd}
.map-nav .nb:last-child{border-bottom:0}
.map-nav svg{display:block;width:29px;height:29px}

/* what the map is showing, and what it is NOT: the product states its limits
   rather than quietly dropping records */
.map-read{
  position:absolute;left:12px;bottom:12px;
  display:flex;flex-wrap:wrap;align-items:center;column-gap:12px;row-gap:4px;
  /* wraps before it reaches the attribution control's corner */
  width:max-content;max-width:min(calc(100% - 24px),58%);
  padding:8px 12px;border-radius:8px;border:1px solid var(--line);
  background:rgba(11,13,16,.9);
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  font-size:12px;line-height:1.35;color:var(--dim);
}
.map-read .n{color:var(--ink);font-variant-numeric:tabular-nums}
.map-read .warn{color:var(--warn)}
.map-read .leg{display:inline-flex;align-items:center;gap:6px;color:var(--muted)}
.map-read .leg i{width:10px;height:10px;border-radius:50%;background:var(--ok);flex:none}
.map-read .leg i.imp{background:var(--muted);margin-left:4px}

/* ---------- trust strip ---------- */
.trust{border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:var(--s3) 0;background:var(--surface)}
.trust-row{display:flex;justify-content:space-between;gap:var(--s3);flex-wrap:wrap;font-size:13px;font-weight:500;color:var(--muted)}
.trust-row span{display:inline-flex;align-items:center;gap:9px}
.trust-row i{width:5px;height:5px;border-radius:50%;background:var(--brand);flex:none}
@media(max-width:980px){.trust-row{justify-content:flex-start}}

/* ---------- feature list rows ---------- */
.lrows{border-top:1px solid var(--line)}
.lrow{display:flex;gap:var(--s3);padding:var(--s3) 0;border-bottom:1px solid var(--line)}
.lrow .ln{
  font-family:'Space Grotesk',sans-serif;font-weight:700;font-size:13px;color:var(--brand);
  min-width:26px;padding-top:3px;letter-spacing:.06em;
}
.lrow h3{font-size:16px;margin-bottom:4px;letter-spacing:-0.01em}
.lrow p{color:var(--muted);font-size:14px}

/* ---------- steps (product page chapters) ---------- */
.chapter{padding:var(--s6) 0}
.chapter-num{
  font-family:'Space Grotesk',sans-serif;font-weight:700;font-size:13px;
  color:var(--brand);letter-spacing:.12em;margin-bottom:var(--s2);display:block;
}

/* ---------- security page ---------- */
.plain{max-width:720px}
.plain h2{font-size:var(--t-h4);margin:var(--s5) 0 var(--s2)}
.plain p{color:var(--muted);margin-bottom:var(--s2);font-size:15.5px;text-wrap:pretty}
.plain p b{color:var(--ink);font-weight:600}
.plain ul{color:var(--muted);margin:0 0 var(--s2) 20px;font-size:15.5px;display:grid;gap:var(--s1)}
.callout{
  background:var(--surface);border:1px solid var(--line);border-left:3px solid var(--brand);
  border-radius:var(--r-sm);padding:var(--s3);margin:var(--s4) 0;
}
.callout h3{font-size:16px;margin-bottom:var(--s1);letter-spacing:-0.01em}
.callout p{color:var(--muted);font-size:14.5px;margin-bottom:var(--s1)}
.callout p:last-child{margin-bottom:0}

/* ---------- contact / forms ---------- */
.contact-band{background:var(--surface);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.contact-grid{display:grid;grid-template-columns:38.2fr 61.8fr;gap:var(--s6)}
@media(max-width:980px){.contact-grid{grid-template-columns:1fr;gap:var(--s4)}}
form{display:grid;gap:var(--s2)}
.frow{display:grid;grid-template-columns:1fr 1fr;gap:var(--s2)}
@media(max-width:640px){.frow{grid-template-columns:1fr}}
label{font-size:13px;font-weight:500;color:var(--muted);display:grid;gap:6px}
input,textarea,select{
  background:var(--canvas);border:1px solid var(--line-strong);border-radius:6px;
  padding:12px 14px;color:var(--ink);font:15px 'Inter',sans-serif;width:100%;
  transition:border-color var(--d-2) var(--ease);
}
input:focus,textarea:focus,select:focus{outline:none;border-color:var(--brand)}
textarea{resize:vertical;min-height:110px}
.fcheck{display:flex !important;flex-direction:row;gap:10px;align-items:flex-start;font-size:13px;color:var(--muted);font-weight:400;text-transform:none;letter-spacing:0}
.fcheck span{flex:1;line-height:1.5}
.fcheck input{width:auto;margin-top:2px;accent-color:var(--brand)}
.fcheck a{color:var(--brand)}
.form-note{font-size:12.5px;color:var(--dim)}
/* the live region is always rendered (role=status in markup) so screen
   readers announce injected text; the box styling appears only with content */
.formmsg{display:block;font-size:14px;color:var(--ink)}
.formmsg:not(:empty){background:var(--canvas);border:1px solid var(--brand);border-radius:var(--r-sm);padding:14px 16px;margin-top:var(--s2)}
.contact-info{display:grid;gap:var(--s1);align-content:start}
.contact-info .row{display:grid;grid-template-columns:110px 1fr;gap:var(--s2);align-items:baseline;font-size:15px;padding:12px 0;border-bottom:1px solid var(--line)}
.contact-info .row>span:first-child{color:var(--dim);font-size:13px}
.contact-info .row>span+span{color:var(--muted)}
.contact-info .row a{color:var(--muted)}
.contact-info .row a:hover{color:var(--ink)}

/* ---------- CTA band ---------- */
.cta-band{background:var(--surface);border-top:1px solid var(--line);border-bottom:1px solid var(--line);text-align:center}
.cta-band .section-title{margin-bottom:var(--s2)}
.cta-band .section-sub{margin-left:auto;margin-right:auto;margin-bottom:var(--s4)}
.cta-band .hero-ctas{justify-content:center}

/* ---------- legal pages ---------- */
.legal{max-width:760px;padding-bottom:var(--s6)}
.legal h1{font-size:clamp(32.944px,4.4vw,48px);margin-bottom:var(--s2)}
.legal .updated{color:var(--dim);font-size:13.5px;margin-bottom:var(--s5)}
.legal h2{font-size:22px;margin:var(--s5) 0 var(--s2)}
.legal h3{font-size:17px;margin:var(--s3) 0 var(--s1)}
.legal p{color:var(--muted);margin-bottom:var(--s2);font-size:15px}
.legal ul{color:var(--muted);margin:0 0 var(--s2) 20px;font-size:15px;display:grid;gap:var(--s1)}
.legal a{color:var(--brand)}
.legal .callout{margin:var(--s3) 0}

/* ---------- footer ---------- */
footer{padding:var(--s6) 0 var(--s5);font-size:13.5px;color:var(--muted)}
.foot{display:flex;justify-content:space-between;align-items:center;gap:var(--s3);flex-wrap:wrap}
.foot .brand{font-size:17px}
.foot-tag{margin-top:10px;font-size:13.5px;color:var(--dim)}
.foot-links{display:flex;gap:var(--s3);flex-wrap:wrap;margin-top:var(--s4);font-size:13.5px}
.foot-links a{color:var(--muted);transition:color var(--d-2) var(--ease)}
.foot-links a:hover{color:var(--ink)}
.foot-legal{margin-top:var(--s4);padding-top:var(--s4);border-top:1px solid var(--line)}
.foot-legal p{font-size:12.5px;line-height:1.75;color:var(--dim);margin-bottom:10px}
.foot-legal p:last-child{margin-bottom:0}

/* ============================================================
   elevation components (2026-09): photo layers, chrome, bands,
   relay diagram, coexist / persona / feature-index grids.
   Everything below uses only the tokens defined at the top.
   ============================================================ */

/* ---------- generated-photo layers ----------
   Each ph-* class stacks a real photo over the existing gradient;
   until the file exists in /images/photos/ the gradient shows alone. */
.ph-formwork{background-image:url('/images/photos/thumb-formwork.jpg'),linear-gradient(135deg,#20242b 0%,#171b21 55%,#12151a 100%)}
.ph-scaffold{background-image:url('/images/photos/thumb-scaffold.jpg'),linear-gradient(135deg,#3A4048 0%,#22262C 100%)}
.ph-blinding{background-image:url('/images/photos/thumb-blinding.jpg'),linear-gradient(135deg,#434A53 0%,#262B31 100%)}
.ph-trench{background-image:url('/images/photos/thumb-trench.jpg'),linear-gradient(135deg,#3E444D 0%,#23282e 100%)}
.ph-membrane{background-image:url('/images/photos/thumb-membrane.jpg'),linear-gradient(135deg,#2c3138 0%,#1a1e24 100%)}
.ph-crane{background-image:url('/images/photos/thumb-crane.jpg'),linear-gradient(135deg,#464C55 0%,#282D34 100%)}
.ph-rebar{background-image:url('/images/photos/thumb-rebar.jpg'),linear-gradient(135deg,#33383f 0%,#1d2127 100%)}
.ph-kerb{background-image:url('/images/photos/thumb-kerb.jpg'),linear-gradient(135deg,#3b4149 0%,#242930 100%)}
.ph-kerbform{background-image:url('/images/photos/thumb-kerbform.jpg'),linear-gradient(135deg,#40464e 0%,#252a30 100%)}
.ph-barriers{background-image:url('/images/photos/thumb-barriers.jpg'),linear-gradient(135deg,#4a4038 0%,#2a2620 100%)}
.ph-pit7-trench{background-image:url('/images/photos/thumb-pit7-trench.jpg'),linear-gradient(135deg,#3c4149 0%,#22272d 100%)}
.ph-pit7-base{background-image:url('/images/photos/thumb-pit7-base.jpg'),linear-gradient(135deg,#474d56 0%,#282d33 100%)}

.stamp.ph-stamp-hero{
  background-image:url('/images/photos/photo-stamp-hero.jpg'),
    radial-gradient(120% 90% at 20% 0%,#232830 0%,transparent 60%),
    radial-gradient(90% 70% at 85% 100%,#12161c 0%,transparent 55%),
    linear-gradient(160deg,#1d2229 0%,#14181e 45%,#0e1116 100%);
  background-size:cover;background-position:center;
}
.phone-screen.ph-viewfinder{
  background-image:url('/images/photos/photo-viewfinder.jpg'),
    radial-gradient(130% 80% at 15% 5%,#272d36 0%,transparent 55%),
    radial-gradient(100% 70% at 90% 95%,#10141a 0%,transparent 60%),
    linear-gradient(165deg,#1e242c 0%,#151a21 50%,#0d1015 100%);
  background-size:cover;background-position:center;
}

/* dusk photo behind a CTA band, dark enough to stay atmosphere */
.cta-band.photo{position:relative;overflow:hidden}
.cta-band.photo::before{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.12;
  background:url('/images/photos/photo-site-dusk.jpg') center/cover no-repeat;
}
.cta-band.photo>.container{position:relative}

/* ---------- browser chrome on the register window ---------- */
.mock-chrome{
  display:flex;align-items:center;gap:var(--s2);
  padding:8px var(--s2);border-bottom:1px solid var(--line);
  background:color-mix(in srgb,var(--surface) 55%,var(--canvas));
}
.mock-chrome .dots{display:flex;gap:5px;flex:1}
.mock-chrome .dots i{width:8px;height:8px;border-radius:50%;background:var(--line-strong)}
.mock-chrome .url{
  flex:0 1 300px;height:23px;display:inline-flex;align-items:center;justify-content:center;gap:6px;
  border-radius:99px;background:var(--canvas);border:1px solid var(--line);
  font-size:10.5px;color:var(--dim);white-space:nowrap;padding:0 12px;
}
.mock-chrome .url svg{width:8px;height:9px;flex:none;color:var(--dim)}
.mock-chrome .spacer{flex:1}

/* the "suggested" chip now lives with the replica, as .ra-sugg */

/* ---------- surface band sections ---------- */
.band{background:var(--surface);border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:var(--s6) 0}

/* ---------- the relay: five stops vs one motion ---------- */
/* minmax(0,1fr) everywhere: the storyboard row must never hand its
   one-line width up the chain and stretch the page on small screens */
/* ---------- one photo, two journeys ----------
   Two cards, the same photo at the top of each. Left: what the file carries
   when it leaves the camera, where it goes today and what it loses at each
   hand-off. Right: the record Wenvar makes once and the four artefacts that
   draw from it. Real words, no glyph puzzles.

   The two cards share one set of rows (subgrid): label, photo, the box,
   four steps, note. So the rule under the photo, the box, every step's
   bullet and the rule above the note sit on the same line in both columns,
   whatever wraps. The steps list is a subgrid of the card for the same
   reason. */
.relay{display:grid;gap:var(--s3);grid-template-columns:repeat(2,minmax(0,1fr))}
.relay-row{
  border:1px solid var(--line);border-radius:var(--r-lg);background:var(--canvas);
  padding:var(--s3);display:grid;grid-template-rows:subgrid;grid-row:span 8;row-gap:var(--s2);min-width:0;
}
.relay-row.after{border-color:color-mix(in srgb,var(--brand) 40%,var(--line))}
.relay-label{
  margin:0;font-size:var(--t-meta);font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);
}
.relay-row.after .relay-label{color:var(--brand)}
.relay-start{display:flex;align-items:center;gap:var(--s2);padding-bottom:var(--s2);border-bottom:1px solid var(--line)}
.relay-start .jt{
  flex:none;width:58px;height:42px;border-radius:5px;border:1px solid var(--line-strong);
  background-color:#171b21;background-size:cover;background-position:center;
}
.relay-start b{display:block;font-size:12.5px;font-weight:600;color:var(--ink);line-height:1.3}
.relay-start span{display:block;font-size:11.5px;color:var(--dim);line-height:1.35;margin-top:2px}
.jsteps{list-style:none;margin:0;padding:0;display:grid;grid-template-rows:subgrid;grid-row:span 4;row-gap:var(--s2)}
.jstep{position:relative;display:grid;grid-template-columns:58px minmax(0,1fr);gap:var(--s1);padding-left:16px}
.jstep::before{content:"";position:absolute;left:0;top:6px;width:7px;height:7px;border-radius:50%;background:var(--line-strong)}
.jstep::after{content:"";position:absolute;left:3px;top:16px;bottom:-15px;width:1px;background:var(--line)}
.jstep:last-child::after{display:none}
.jwhen{font-size:11px;color:var(--dim);font-variant-numeric:tabular-nums;line-height:1.4;padding-top:1px}
.jwhat{min-width:0}
.jwhat b{display:block;font-size:12.5px;font-weight:600;color:var(--ink);line-height:1.35}
.jwhat code{display:block;font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:11px;color:var(--muted);line-height:1.5}
.jwhat q{display:block;font-size:11.5px;color:var(--muted);line-height:1.5;quotes:"\201C" "\201D"}
.jwhat .lost,.jwhat .kept{display:block;margin-top:1px;font-size:11.5px;line-height:1.4}
.jwhat .lost{color:var(--warn)}
.jwhat .kept{color:var(--muted)}
.relay-row.after .jstep::before{background:var(--brand)}
.relay-row.after .jstep::after{background:color-mix(in srgb,var(--brand) 40%,var(--line))}
.relay-note{margin:0;align-self:start;padding-top:var(--s2);border-top:1px solid var(--line);color:var(--dim);font-size:12.5px;line-height:1.4}
.relay-row.after .relay-note{color:var(--muted)}
/* the record, as the register shows it */
.relay-record{
  margin:0;display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  border:1px solid color-mix(in srgb,var(--brand) 32%,var(--line-strong));
  border-radius:var(--r-sm);background:var(--surface);padding:8px 12px;min-width:0;
}
.relay-record .rr-time{font-size:11px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.relay-record .rr-place{font-size:11px;color:var(--dim);white-space:nowrap}
.relay-record .rr-cap{flex:1 1 140px;min-width:0;font-size:11.5px;color:var(--ink);line-height:1.35}
.relay-record .rr-tag{
  flex:none;padding:1px 8px;border-radius:99px;font-size:10px;white-space:nowrap;
  border:1px solid color-mix(in srgb,var(--brand) 55%,transparent);color:var(--brand);background:var(--canvas);
}
.relay-record .rr-who{
  flex:none;width:22px;height:22px;border-radius:50%;background:var(--canvas);border:1px solid var(--line-strong);
  display:inline-flex;align-items:center;justify-content:center;font-size:8.5px;font-weight:600;color:var(--muted);
}
/* the file's own record, for the left card: the time it carries and the
   fields it does not. Same box, dashed, so the two read as a pair. */
.relay-record.bare{border:1px dashed var(--line-strong);background:transparent}
.relay-record.bare .rr-cap{color:var(--warn)}
@media(max-width:820px){
  .relay{grid-template-columns:minmax(0,1fr)}
}

/* ---------- coexist cards ---------- */
.coexist-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s3);margin-top:var(--s4)}
@media(max-width:980px){.coexist-grid{grid-template-columns:minmax(0,1fr)}}
.coexist-card{padding:var(--s3);display:flex;flex-direction:column;gap:var(--s2);transition:transform var(--d-2) var(--ease),border-color var(--d-2) var(--ease)}
.coexist-card:hover{transform:translateY(-2px);border-color:var(--line-strong)}
.coexist-card h3{font-size:16.5px;letter-spacing:-0.01em}
.coexist-card>p{color:var(--muted);font-size:13.5px;line-height:1.6;flex:1}
.coexist-visual{border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden;background:var(--canvas)}
/* equal-height visuals at desktop so the three card titles share a baseline;
   the height is set by the tallest artefact, one A4 record page */
@media(min-width:981px){
  .coexist-visual{height:345px;display:flex;flex-direction:column;justify-content:center}
}
.coexist-note{margin-top:var(--s3);max-width:80ch;color:var(--dim);font-size:12px;line-height:1.6}

/* one record page of the real PDF report (coexist card 1 + product 05).
   Sizes are em of --pf so the same page renders small in a card and
   large on the product page; Helvetica because the PDF has only that. */
.coexist-visual.paper-wrap{
  display:flex;align-items:center;justify-content:center;padding:var(--s1);
  background:color-mix(in srgb,var(--canvas) 60%,#000);
}
.pdf-page{
  width:var(--pw,230px);aspect-ratio:1/1.414;overflow:hidden;
  display:flex;flex-direction:column;padding:1.55em;
  background:#fff;color:#1F1F21;font-family:Helvetica,Arial,sans-serif;
  font-size:var(--pf,8px);line-height:1.35;
  box-shadow:0 13px 34px -13px rgba(0,0,0,.6);
}
.pp-head{display:flex;justify-content:space-between;align-items:flex-start;gap:1em;margin-bottom:.85em}
.pp-num{font-size:1.75em;font-weight:700;line-height:1;color:#0E6E80}
.pp-pill{
  border:1px solid rgba(31,139,80,.5);border-radius:2px;padding:.3em .5em;
  color:#1F8B50;font-size:.72em;font-weight:700;letter-spacing:.07em;text-transform:uppercase;white-space:nowrap;
}
.pp-photo{flex:1 1 auto;min-height:0;border:1px solid #D9D9DB;background-size:cover;background-position:center}
.pp-cap{font-size:1.15em;line-height:1.35;margin-top:.85em}
.pp-capnote{font-size:.78em;color:#737378;margin-top:.35em}
.pp-rule{height:1px;background:#D9D9DB;margin:.8em 0}
.pp-grid{display:grid;grid-template-columns:1fr 1fr;column-gap:1.1em;row-gap:.7em}
.pp-l{display:block;font-size:.75em;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:#737378}
.pp-v{display:block;margin-top:.2em;line-height:1.3}
.pp-foot{
  display:flex;justify-content:space-between;gap:.7em;margin-top:.8em;padding-top:.55em;
  border-top:1px solid #D9D9DB;font-size:.78em;color:#737378;white-space:nowrap;
}
.pp-foot span:first-child{overflow:hidden;text-overflow:ellipsis}
/* the same page, read at arm's length, on the product page */
.pdf-lg{--pw:min(420px,100%);--pf:11px;margin:0 auto;box-shadow:0 21px 55px -21px rgba(0,0,0,.7)}
@media(max-width:980px){.paper-wrap .pdf-page{--pw:280px;--pf:9.5px}}
@media(max-width:430px){.pdf-lg{--pf:9px}}

/* the register exported as the real Excel workbook (coexist card 2) */
.coexist-visual.xl-wrap{display:block;background:#fff;overflow:hidden}
@media(max-width:980px){.coexist-visual.xl-wrap{height:290px}}
.xl{
  width:473px;display:grid;grid-template-columns:15px 64px 68px 100px 56px 74px 48px 48px;
  font-family:Calibri,Carlito,'Segoe UI',system-ui,sans-serif;font-size:7.5px;line-height:1.3;color:#1F1F21;
}
.xl-let,.xl-gut{
  display:flex;align-items:center;justify-content:center;min-height:15px;font-style:normal;
  background:#F1F1F1;border-right:1px solid #C9C9C9;border-bottom:1px solid #D9D9D9;
  font-size:7px;color:#5A6069;
}
.xl-let{min-height:12px;border-bottom-color:#C9C9C9}
.xl-cell{padding:3px 4px;border-right:1px solid #D9D9D9;border-bottom:1px solid #D9D9D9;overflow:hidden}
.xl-wide{grid-column:2 / -1;border-right:0}
.xl-t1{font-size:11px;font-weight:700;padding:4px}
.xl-t2{color:#666666;padding-bottom:5px}
.xl-h{
  background:#0E6E80;color:#FFFFFF;font-weight:700;padding:5px 4px;border-right-color:#0E6E80;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.xl-pic{padding:3px}
.xl-pic i{display:block;aspect-ratio:4/3;border-radius:1px;background-size:cover;background-position:center}
.xl-n{text-align:right}

/* the real import screen (coexist card 3) */
.coexist-visual.imp{display:flex;flex-direction:column;justify-content:flex-start;gap:var(--s1);padding:var(--s2)}
.imp-drop{
  border:1px dashed var(--line-strong);border-radius:var(--r-sm);padding:10px 8px;
  display:flex;flex-direction:column;gap:2px;align-items:center;text-align:center;
}
.imp-drop b{font-size:9.5px;font-weight:600;color:var(--muted)}
.imp-drop span{font-size:8px;color:var(--dim)}
.imp-ready{font-size:10px;font-weight:600;color:var(--ink)}
.imp-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;flex:1;min-height:0}
.imp-card{
  display:flex;flex-direction:column;gap:3px;overflow:hidden;padding:7px 6px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);
}
.imp-card b{font-size:17px;font-weight:700;line-height:1;color:var(--ok);font-variant-numeric:tabular-nums}
.imp-card.mid b{color:var(--muted)}
.imp-card.bad{border-color:color-mix(in srgb,var(--bad) 40%,transparent);background:color-mix(in srgb,var(--bad) 6%,var(--surface))}
.imp-card.bad b{color:var(--bad)}
.imp-l{display:flex;align-items:flex-start;gap:4px;font-size:8px;font-weight:600;line-height:1.25;color:var(--muted)}
.imp-l i{flex:none;width:5px;height:5px;border-radius:50%;margin-top:2.5px;background:var(--ok)}
.imp-card.mid .imp-l i{background:var(--muted)}
.imp-card.bad .imp-l i{background:var(--bad)}
.imp-b{font-size:7px;line-height:1.32;color:var(--dim)}
.imp-dupe{font-size:9px;line-height:1.4;color:var(--dim)}
.imp-table{display:grid;gap:0;border-top:1px solid var(--line)}
.imp-table .itr{
  display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr) 46px 32px;
  gap:6px;align-items:center;padding:5px 0;border-bottom:1px solid var(--line);font-size:8px;
}
.imp-table .itr b{font-weight:500;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.imp-table .itr span{color:var(--dim);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.imp-table .itr i{font-style:normal;color:var(--dim);font-variant-numeric:tabular-nums}
.imp-table .itr em{font-style:normal;color:var(--ok);text-align:right}

/* import classifier (product 06) */
.classify{display:grid;gap:0;padding:var(--s1) 0}
.classify .crow{display:flex;align-items:center;gap:9px;padding:7px var(--s2);font-size:11.5px;color:var(--muted)}
.classify .crow+.crow{border-top:1px solid var(--line)}
.classify .crow i{width:6px;height:6px;border-radius:50%;flex:none;background:var(--ok)}
.classify .crow.mid i{background:var(--muted)}
.classify .crow.none i{background:var(--bad)}
.classify .crow.skip i{background:transparent;border:1px solid var(--line-strong)}
.classify .crow b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}

/* ---------- persona cards ---------- */
.persona-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s3);margin-top:var(--s4)}
@media(max-width:980px){.persona-grid{grid-template-columns:minmax(0,1fr)}}
.persona-card{
  padding:var(--s3);border-top:3px solid var(--brand);
  transition:transform var(--d-2) var(--ease),border-color var(--d-2) var(--ease);
}
.persona-card:hover{transform:translateY(-2px);border-color:var(--line-strong);border-top-color:var(--brand)}
.persona-card .role{
  font-size:var(--t-meta);font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--brand);display:block;margin-bottom:var(--s2);
}
.persona-card p{color:var(--muted);font-size:14px;line-height:1.65}
.persona-card p b{color:var(--ink);font-weight:600}

/* ---------- feature index (product) ---------- */
.feature-index{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 var(--s5);border-top:1px solid var(--line);margin-top:var(--s4)}
@media(max-width:980px){.feature-index{grid-template-columns:minmax(0,1fr)}}
.feature-index .lrow:first-child{border-top:0}

/* ---------- product-page mock extras ---------- */
/* the tagging sheet the app presents right after the shutter, at its
   medium detent over the camera: the photo keeps uploading behind it */
.qt-dim{position:absolute;inset:0;z-index:2;background:rgba(4,6,9,.42)}
.qt-sheet{
  position:absolute;left:0;right:0;bottom:0;z-index:3;
  background:var(--surface);border-top:1px solid var(--line);
  border-radius:14px 14px 26px 26px;padding:13px 14px 15px;
  display:flex;flex-direction:column;gap:8px;
}
.qt-sheet .qt-head{display:flex;align-items:center;gap:10px}
.qt-sheet .qt-thumb{
  width:40px;height:40px;border-radius:9px;flex:none;border:1px solid var(--line-strong);
  background-color:#171b21;background-size:cover;background-position:center;
}
.qt-sheet .qt-titles{min-width:0}
.qt-sheet .qt-titles b{display:block;font-size:12px;font-weight:600;color:var(--ink);line-height:1.3}
.qt-sheet .qt-titles span{display:block;font-size:8.8px;color:var(--dim);line-height:1.35}
.qt-sheet .qt-typed{display:flex;gap:5px;flex-wrap:wrap}
.qt-sheet .qt-typed span{
  padding:3px 9px;border-radius:99px;font-size:9.5px;font-weight:500;
  color:var(--brand-ink);background:var(--brand);
}
.qt-sheet .qt-field{
  display:block;border:1px solid var(--line-strong);border-radius:var(--r-sm);
  padding:7px 9px;font-size:10px;color:var(--dim);background:var(--canvas);
}
.qt-sheet .qt-label{
  display:block;font-size:8px;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--dim);
}
.qt-sheet .qt-recent{display:flex;gap:5px;flex-wrap:wrap}
.qt-sheet .qt-recent span{
  padding:3px 9px;border-radius:99px;border:1px solid var(--line-strong);
  font-size:9.5px;color:var(--muted);background:var(--canvas);
}
.qt-sheet .qt-actions{display:flex;gap:8px;margin-top:2px}
.qt-sheet .qt-actions span{
  flex:1;text-align:center;padding:7px 0;border-radius:99px;
  font-size:10.5px;font-weight:600;color:var(--brand-ink);
}
.qt-sheet .qt-skip{background:var(--warn)}
.qt-sheet .qt-done{background:var(--brand)}

/* the column picker is now drawn at the product's own size, as .ra-colpop */

/* upload queue card (product 02) */
.queue-card{padding:var(--s5);display:flex;flex-direction:column;gap:var(--s3);align-items:center}
.queue-card .qnote{color:var(--dim);font-size:13px;text-align:center;max-width:26em}

/* about page: what happens next */
.next-steps{counter-reset:step;border-top:1px solid var(--line);margin-top:var(--s4)}
.next-steps .lrow .ln{min-width:26px}

/* upload queue rows (product 02): the queue the copy actually describes */
.queue-list{width:100%;max-width:420px;border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden;background:var(--canvas)}
.queue-list .qrow{display:flex;align-items:center;gap:var(--s2);padding:10px var(--s2)}
.queue-list .qrow+.qrow{border-top:1px solid var(--line)}
.queue-list .qrow .reg-thumb{width:38px;height:28px;flex:none}
.queue-list .qcap{flex:1;min-width:0;display:block}
.queue-list .qcap b{display:block;color:var(--ink);font-size:11.5px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.queue-list .qcap span{display:block;color:var(--dim);font-size:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.queue-list .badge{flex:none}
.queue-list .qfoot{display:flex;justify-content:space-between;align-items:center;gap:var(--s2);padding:9px var(--s2);border-top:1px solid var(--line);background:var(--surface);font-size:11px;color:var(--dim)}
.queue-list .qretry{border:1px solid var(--line-strong);border-radius:99px;padding:4px 12px;font-size:10.5px;font-weight:500;color:var(--muted)}
