/* ============================================================
   The World of Pirates Online — landing site
   Self-contained: no CDNs, no external requests.
   Fonts: IM Fell English + EB Garamond (SIL OFL 1.1, see fonts/)
   ============================================================ */

@font-face{
  font-family:"IM Fell English";
  src:url("fonts/IMFellEnglish/IMFeENrm28P.ttf") format("truetype");
  font-weight:400; font-style:normal; font-display:swap;
}
@font-face{
  font-family:"IM Fell English";
  src:url("fonts/IMFellEnglish/IMFeENit28P.ttf") format("truetype");
  font-weight:400; font-style:italic; font-display:swap;
}
@font-face{
  font-family:"EB Garamond";
  src:url("fonts/EBGaramond/EBGaramond[wght].ttf") format("truetype-variations"),
      url("fonts/EBGaramond/EBGaramond[wght].ttf") format("truetype");
  font-weight:400 800; font-style:normal; font-display:swap;
}

:root{
  --abyss:#05101a;
  --deep:#0b1a26;
  --hull:#12242f;
  --plank:#1b3140;
  --line:rgba(201,162,39,.22);

  --gold:#c9a227;
  --gold-lt:#e8cf7d;
  --gold-dk:#8a6d15;

  --parch:#e9dfc6;
  --parch-dim:#a99f8b;
  --danger:#e0685c;
  --ok:#79b47a;

  /* --- nautical dressing (added 2026-08-03) ------------------------
     Wood and parchment are ACCENT surfaces only. The page floor stays
     the deep-sea blue above so the site does not turn brown; the wood
     is warm-dark enough to sit under gold without fighting the logo. */
  --wood-dk:#1a120b;
  --wood:#241a11;
  --wood-lt:#37271a;

  --paper:#ede1c2;      /* parchment sheet, light end   */
  --paper-dk:#d5c39b;   /* parchment sheet, shaded end  */
  --ink:#4a3a22;        /* body text ON parchment       */
  --ink-dk:#2f2413;     /* headings ON parchment        */
  --ink-mid:#5b4930;

  /* Twisted-hemp rope. One gradient, reused by every rope surface. */
  --rope:repeating-linear-gradient(112deg,
      #4e3720 0 3px, #a07c46 3px 7px, #d8ba81 7px 9px, #a07c46 9px 12px, #4e3720 12px 14px);

  /* Procedural textures — inline SVG turbulence, data: URI.
     No file, no request. Satisfies the CSP (img-src 'self' data:). */
  --tex-grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='150' height='150' filter='url(%23g)' opacity='0.5'/%3E%3C/svg%3E");
  --tex-wood:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='150'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.014 0.62' numOctaves='4'/%3E%3C/filter%3E%3Crect width='300' height='150' filter='url(%23w)' opacity='0.55'/%3E%3C/svg%3E");
  --tex-blotch:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='340' height='340'%3E%3Cfilter id='b'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.012' numOctaves='4'/%3E%3C/filter%3E%3Crect width='340' height='340' filter='url(%23b)' opacity='0.55'/%3E%3C/svg%3E");

  --display:"IM Fell English", Georgia, "Times New Roman", serif;
  --body:"EB Garamond", Georgia, "Times New Roman", serif;

  --wrap:1120px;
  --r:3px;
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  margin:0;
  /* faint canvas tooth over the sea blue — texture without a texture file */
  background:var(--tex-grain), var(--deep);
  background-blend-mode:soft-light;
  color:var(--parch);
  font-family:var(--body);
  font-size:19px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

img{max-width:100%;height:auto;display:block}

.wrap{width:100%;max-width:var(--wrap);margin-inline:auto;padding-inline:24px}

.skip{
  position:absolute;left:-9999px;top:0;z-index:200;
  background:var(--gold);color:var(--abyss);padding:10px 16px;
}
.skip:focus{left:8px;top:8px}

:focus-visible{outline:2px solid var(--gold-lt);outline-offset:3px}

/* ---------------- buttons ---------------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--display);
  font-size:1rem;letter-spacing:.06em;text-transform:uppercase;
  padding:.72em 1.5em;border-radius:var(--r);
  border:1px solid transparent;cursor:pointer;
  text-decoration:none;white-space:nowrap;
  transition:transform .12s ease, box-shadow .18s ease, background .18s ease, border-color .18s ease;
}
.btn:active{transform:translateY(1px)}

.btn-gold{
  color:#1a1206;
  background:linear-gradient(180deg,var(--gold-lt) 0%, var(--gold) 52%, var(--gold-dk) 100%);
  border-color:rgba(255,240,190,.5);
  box-shadow:0 1px 0 rgba(255,246,214,.5) inset, 0 6px 18px -8px rgba(0,0,0,.9);
  font-weight:600;
}
.btn-gold:hover{
  background:linear-gradient(180deg,#f4e2a4 0%, #d8b135 52%, #9a7c1c 100%);
  box-shadow:0 1px 0 rgba(255,250,230,.6) inset, 0 8px 22px -8px rgba(0,0,0,1);
}

.btn-ghost{
  color:var(--gold-lt);
  background:rgba(233,223,198,.03);
  border-color:rgba(201,162,39,.45);
}
.btn-ghost:hover{background:rgba(201,162,39,.12);border-color:var(--gold)}

.btn-lg{font-size:1.06rem;padding:.85em 1.9em}
.btn-block{display:flex;width:100%}
.btn[aria-disabled="true"]{opacity:.45;pointer-events:none}

/* Same trap as `.pane label[hidden]` further down: an author `display` beats
   the UA's `[hidden]{display:none}`, so a `.btn` — and every `.btn-block` —
   ignored the hidden attribute and stayed on screen. That is why the
   "Download the Client" button showed under a *pending* signup (app.js sets
   `cta.hidden = true` there and nothing happened). Added 2026-08-17. */
.btn[hidden]{display:none}

.linkish{
  background:none;border:0;padding:0;cursor:pointer;
  color:var(--gold-lt);font-family:var(--body);font-size:inherit;
  text-decoration:underline;text-underline-offset:3px;
}

/* ---------------- nav ---------------- */
.nav{
  position:fixed;inset:0 0 auto 0;z-index:60;
  transition:background .25s ease, border-color .25s ease, backdrop-filter .25s ease;
  border-bottom:1px solid transparent;
}
.nav.is-stuck{
  /* dark oiled plank: grain + seam over the near-black sea blue */
  background:
    var(--tex-wood),
    linear-gradient(180deg, rgba(55,39,26,.55), rgba(26,18,11,.75)),
    rgba(5,16,26,.96);
  background-blend-mode:soft-light, normal, normal;
  border-bottom-color:rgba(201,162,39,.45);
  backdrop-filter:blur(9px);
}
/* rope laid along the bottom edge of the stuck bar */
.nav.is-stuck::after{
  content:"";position:absolute;inset:auto 0 -4px 0;height:4px;
  background:var(--rope);
  box-shadow:inset 0 2px 3px -1px rgba(0,0,0,.9), 0 2px 6px -3px #000;
}
.nav-in{display:flex;align-items:center;gap:20px;min-height:74px}
.brand{flex:0 0 auto;display:block}
.brand img{width:186px;height:auto;filter:drop-shadow(0 2px 8px rgba(0,0,0,.8))}
.nav-links{margin-left:auto;display:flex;align-items:center;gap:8px}
.nav-links a{
  font-family:var(--display);text-transform:uppercase;letter-spacing:.08em;
  font-size:.86rem;color:var(--parch);text-decoration:none;padding:.6em .9em;
  border-radius:var(--r);
}
.nav-links a:hover{color:var(--gold-lt);background:rgba(201,162,39,.09)}
.nav-links .btn{font-size:.84rem;padding:.62em 1.15em}
/* signed-in greeting — swapped in for the Log In button by app.js */
.nav-greet{
  font-family:var(--display);text-transform:uppercase;letter-spacing:.08em;
  font-size:.86rem;color:var(--gold-lt);padding:.6em .9em;white-space:nowrap;
}

@media (max-width:760px){
  .nav-links a{display:none}
  .brand img{width:150px}
  .nav-in{min-height:62px}
}
@media (max-width:560px){
  /* only one nav CTA fits; the hero carries both anyway */
  .nav-links [data-auth-open="login"],.nav-greet{display:none}
  .brand img{width:128px}
  .nav-links .btn{font-size:.78rem;padding:.6em .95em}
}

/* ---------------- hero ---------------- */
.hero{
  position:relative;
  min-height:100svh;
  display:flex;align-items:center;
  padding:120px 0 90px;
  overflow:hidden;
  background:
    radial-gradient(120% 90% at 50% 8%, #1d3d50 0%, #123045 34%, #0a1c2a 62%, #040d16 100%);
}
/* procedural sea — no image, no external asset */
.hero-sea{position:absolute;inset:0;pointer-events:none}
.hero-sea::before{
  content:"";position:absolute;inset:auto 0 0 0;height:46%;
  background:linear-gradient(180deg, rgba(4,13,22,0) 0%, rgba(3,10,18,.72) 55%, #030a12 100%);
}
/* compass rose watermark, drawn in SVG — sits behind the wordmark */
.compass{
  position:absolute;left:50%;top:46%;
  width:min(780px, 118vw);height:auto;
  transform:translate(-50%,-50%);
  color:rgba(201,162,39,.14);
  animation:spin 260s linear infinite;
}
.compass .c-ring{fill:none;stroke:currentColor;stroke-width:.7}
.compass .c-thin{stroke-width:.4;opacity:.7}
.compass .c-pt{fill:currentColor}
.compass .c-lo{opacity:.35}
.compass .c-mid{opacity:.6}
.compass .c-hi{opacity:1}
@keyframes spin{from{transform:translate(-50%,-50%) rotate(0)}to{transform:translate(-50%,-50%) rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.compass{animation:none}}

.swell{
  position:absolute;left:-25%;width:150%;border-radius:50% 50% 0 0;
  background:radial-gradient(60% 100% at 50% 100%, rgba(90,150,180,.16), rgba(90,150,180,0) 70%);
  animation:roll 15s ease-in-out infinite;
}
.swell.s1{bottom:-14%;height:38%;opacity:.55;animation-duration:17s}
.swell.s2{bottom:-20%;height:46%;opacity:.4;animation-duration:23s;animation-direction:reverse}
.swell.s3{bottom:-26%;height:54%;opacity:.28;animation-duration:29s}
@keyframes roll{
  0%,100%{transform:translateX(-2%) translateY(0)}
  50%    {transform:translateX(2%)  translateY(-1.6%)}
}
@media (prefers-reduced-motion:reduce){.swell{animation:none}}

.hero-in{position:relative;z-index:2;text-align:center}
.hero-logo{
  width:min(660px, 84vw);margin:0 auto 26px;
  filter:drop-shadow(0 14px 40px rgba(0,0,0,.85));
}
.hero-title{
  font-family:var(--display);
  font-size:clamp(2rem, 5.6vw, 3.5rem);
  line-height:1.12;margin:0 0 .5em;font-weight:400;
  color:#fdf6e2;
  text-shadow:0 2px 26px rgba(0,0,0,.9), 0 0 60px rgba(201,162,39,.16);
}
.hero-sub{
  max-width:63ch;margin:0 auto 2em;
  font-size:clamp(1.02rem,1.9vw,1.22rem);
  color:var(--parch-dim);
}
.hero-cta{display:flex;gap:14px;justify-content:center;flex-wrap:wrap}
.hero-note{margin-top:1.9em;font-size:.95rem}
.hero-note a{color:var(--parch-dim);text-decoration:none;border-bottom:1px dotted rgba(201,162,39,.4);padding-bottom:2px}
.hero-note a:hover{color:var(--gold-lt)}
.hero-fade{position:absolute;inset:auto 0 0 0;height:120px;background:linear-gradient(180deg,rgba(11,26,38,0),var(--deep));z-index:1}

/* ---------------- rope dividers ---------------- */
/* A length of hemp between bands. The twist is a tiling image cut at
   a whole number of twist periods (assets/rope-tile.png, ASSETS.md §8);
   the tile is drawn at 2x and laid down at half height, so the repeat
   width stays a whole number of pixels and the seam cannot drift.
   The roundness is in the art now, so only the cast shadow is CSS. */
.rope-rule{position:relative;height:26px;background:var(--deep)}
.rope-rule::before{
  content:"";position:absolute;inset:4px 3% auto 3%;height:18px;
  background:url("assets/rope-tile.png") repeat-x left center/auto 100%;
  filter:drop-shadow(0 4px 7px rgba(0,0,0,.75));
}
/* the knot — a gold lozenge whipped around the middle of the rope */
.rope-rule::after{
  content:"";position:absolute;left:50%;top:50%;width:15px;height:15px;
  transform:translate(-50%,-50%) rotate(45deg);
  background:linear-gradient(135deg,var(--gold-lt),var(--gold) 55%,var(--gold-dk));
  border:1px solid rgba(255,240,190,.55);
  box-shadow:0 3px 9px -3px #000;
}
/* between the wood band and the wood footer — keep the timber continuous */
.rope-rule-foot{background:var(--wood-dk)}

/* ---------------- bands ---------------- */
.band{padding:clamp(64px,9vw,104px) 0;position:relative}

/* ship's deck: the sea blue with a little tooth in it */
.band-deck{
  background:var(--tex-grain), linear-gradient(180deg,#0d1e2b,#0a1926);
  background-blend-mode:soft-light, normal;
  border-block:1px solid var(--line);
}

/* weathered planking — grain, plank seams, warm dark stain */
.band-wood{
  background:
    var(--tex-wood),
    repeating-linear-gradient(180deg,
      rgba(0,0,0,.55) 0 2px,
      rgba(255,255,255,.035) 2px 3px,
      rgba(0,0,0,0) 3px 62px),
    linear-gradient(180deg,var(--wood-lt) 0%, var(--wood) 40%, var(--wood-dk) 100%);
  background-blend-mode:soft-light, normal, normal;
  border-block:1px solid rgba(201,162,39,.3);
}

.h2{
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.7rem,3.6vw,2.5rem);
  margin:0 0 .35em;color:#f6ecd6;
}
/* heading underline is a short length of the same rope — two whole tiles.
   The size is stated in px rather than `auto 100%` so the repeat lands on
   a whole pixel at this height too (52 × 11 is the tile's own 170:36). */
.h2::after{
  content:"";display:block;width:104px;height:11px;margin-top:.5em;
  background:url("assets/rope-tile.png") repeat-x left center/52px 11px;
  filter:drop-shadow(0 2px 3px rgba(0,0,0,.6));
}
.lede{max-width:62ch;color:var(--parch-dim);margin:0 0 2em;font-size:1.06rem}

/* ---------------- download ---------------- */
.dl-grid{display:grid;gap:20px;grid-template-columns:repeat(auto-fit,minmax(268px,1fr));max-width:760px}
.dl-card{
  position:relative;
  background:
    var(--tex-grain),
    linear-gradient(180deg, rgba(27,49,64,.9), rgba(18,36,47,.9));
  background-blend-mode:soft-light, normal;
  border:1px solid var(--line);border-radius:var(--r);
  padding:28px 26px 26px;
}
/* gold corner brackets — the brass-cornered chest look */
.dl-card::before,
.dl-card::after{
  content:"";position:absolute;width:20px;height:20px;pointer-events:none;
  border:2px solid var(--gold);opacity:.7;
}
.dl-card::before{top:6px;left:6px;border-right:0;border-bottom:0}
.dl-card::after{bottom:6px;right:6px;border-left:0;border-top:0}
.dl-card.is-detected::before,
.dl-card.is-detected::after{opacity:1}
.dl-card.is-detected{border-color:rgba(201,162,39,.6);box-shadow:0 0 0 1px rgba(201,162,39,.22), 0 14px 34px -18px #000}
.dl-card h3{font-family:var(--display);font-weight:400;font-size:1.5rem;margin:0 0 .18em;color:#f6ecd6}
/* platform marks beside the download headings — drawn, not image files.
   Both viewBoxes are square so one width rule sizes them alike; the fill
   inherits the heading colour rather than setting its own. */
.plat-mark{
  display:inline-block;vertical-align:-.08em;
  width:.8em;height:auto;margin-right:.36em;
  fill:currentColor;opacity:.9;
}
.dl-meta{margin:0 0 1.3em;color:var(--parch-dim);font-size:.94rem}
.dl-detected{margin-top:1.5em;color:var(--gold-lt);font-size:.98rem}
.fineprint{margin-top:1.2em;color:#7d8b96;font-size:.9rem;max-width:62ch}
code{font-family:ui-monospace,"Cascadia Code",Consolas,monospace;font-size:.86em;background:rgba(0,0,0,.35);padding:.14em .45em;border-radius:2px;color:var(--gold-lt)}

/* ---------------- parchment sheet ---------------- */
/* An aged sheet nailed to the planking. The torn edge is a jittered
   clip-path (deterministic, no image); the shadow is a drop-shadow
   filter so it follows the tear rather than the box. */
.sheet{
  position:relative;
  padding:clamp(34px,5vw,58px) clamp(26px,4.5vw,54px);
  color:var(--ink);
  transform:rotate(-.25deg);
  filter:drop-shadow(0 16px 30px rgba(0,0,0,.6));
  background:
    var(--tex-grain),
    var(--tex-blotch),
    radial-gradient(58% 42% at 9% 91%, rgba(126,92,42,.34), rgba(126,92,42,0) 72%),
    radial-gradient(52% 38% at 91% 10%, rgba(126,92,42,.28), rgba(126,92,42,0) 72%),
    radial-gradient(120% 78% at 50% 0%, rgba(255,252,240,.55), rgba(255,252,240,0) 62%),
    linear-gradient(158deg, var(--paper) 0%, #e3d5ae 48%, var(--paper-dk) 100%);
  background-blend-mode:soft-light, soft-light, normal, normal, normal, normal;
  clip-path:polygon(
    0.7% 1.1%, 12% 0.3%, 26% 1.4%, 39% 0.3%, 53% 1.3%, 67% 0.4%, 81% 1.5%, 93% 0.3%, 99.4% 1.2%,
    99.0% 14%, 99.7% 30%, 98.8% 46%, 99.6% 62%, 98.9% 78%, 99.7% 92%, 99.2% 98.8%,
    88% 99.6%, 74% 98.5%, 60% 99.7%, 46% 98.6%, 32% 99.6%, 18% 98.5%, 6% 99.7%, 0.5% 98.8%,
    1.0% 84%, 0.3% 68%, 1.2% 52%, 0.4% 36%, 1.1% 20%
  );
}
/* ink on paper — everything inside the sheet flips to dark type */
.sheet .h2{color:var(--ink-dk)}
.sheet .lede{color:var(--ink-mid)}
.sheet .feature-list li{color:var(--ink-mid)}
.sheet .feature-list strong{color:var(--ink-dk)}

/* skull-and-crossbones seal — the project mark (see ASSETS.md §8).
   One geometry, shipped in two ink colours: gold for the dark wood
   footer, dark ink for the parchment sheet, where gold-on-paper has
   no contrast to stand on. */
/* 36px ≈ the old inline svg skull (1.2em of the h2) — user call 08-04 */
.skull-mark{width:36px;height:auto}
/* stamped at the head of the sheet, like a seal on the document */
.skull-mark-ink{margin:0 0 .5em;opacity:.9}
/* footer: block-centred tight above the wordmark line */
.skull-mark-foot{display:block;margin:0 auto .45em;opacity:.85}

/* ---------------- about ---------------- */
.about-in .lede,
.about-in .feature-list{max-width:74ch}
.feature-list{list-style:none;padding:0;margin:0;display:grid;gap:16px}
.feature-list li{
  padding-left:34px;position:relative;color:var(--parch-dim);
}
/* anchor bullets, drawn as an inline data: URI (no request) */
.feature-list li::before{
  content:"";position:absolute;left:0;top:.28em;width:21px;height:21px;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237a5a1c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='4' r='2.1'/%3E%3Cpath d='M12 6.1V21'/%3E%3Cpath d='M7.6 9.2h8.8'/%3E%3Cpath d='M4 13.4c0 4.2 3.6 7.6 8 7.6s8-3.4 8-7.6'/%3E%3Cpath d='M2.2 13.4h3.6M18.2 13.4h3.6'/%3E%3C/svg%3E") center/contain no-repeat;
  opacity:.85;
}

/* ---------------- footer ---------------- */
.foot{
  position:relative;overflow:hidden;
  padding:56px 0 60px;
  border-top:1px solid rgba(201,162,39,.3);
  background:
    var(--tex-wood),
    repeating-linear-gradient(180deg,
      rgba(0,0,0,.6) 0 2px,
      rgba(255,255,255,.03) 2px 3px,
      rgba(0,0,0,0) 3px 62px),
    linear-gradient(180deg,var(--wood) 0%, var(--wood-dk) 70%, #120c07 100%);
  background-blend-mode:soft-light, normal, normal;
}
/* ship's wheel watermark — generated gold mark, already the right gold (see ASSETS.md §7) */
.wheel{
  position:absolute;right:-58px;top:50%;transform:translateY(-50%);
  display:block;width:290px;height:auto;pointer-events:none;
  opacity:.13;
}
.foot-in{position:relative;text-align:center}
.foot-brand{font-family:var(--display);font-size:1.15rem;margin:0 0 1em;color:var(--gold-lt);letter-spacing:.04em}
.foot-links{display:flex;gap:6px 22px;justify-content:center;flex-wrap:wrap;margin-bottom:1.6em}
.foot-links a{color:var(--parch-dim);text-decoration:none;font-size:.94rem}
.foot-links a:hover{color:var(--gold-lt)}
.foot-legal{max-width:60ch;margin:0 auto;color:#6d7a85;font-size:.84rem;line-height:1.6}

/* ---------------- modal ---------------- */
.modal{position:fixed;inset:0;z-index:100;display:flex;align-items:center;justify-content:center;padding:20px}
.modal[hidden]{display:none}
.modal-scrim{position:absolute;inset:0;background:rgba(2,8,14,.86);backdrop-filter:blur(4px)}
.modal-card{
  position:relative;width:100%;max-width:440px;
  max-height:calc(100svh - 40px);overflow-y:auto;
  background:linear-gradient(180deg,#14293a,#0c1b27);
  border:1px solid rgba(201,162,39,.4);border-radius:var(--r);
  box-shadow:0 30px 80px -20px #000, 0 0 0 1px rgba(0,0,0,.6);
  padding:28px 30px 30px;
}
.modal-x{
  position:absolute;right:12px;top:8px;
  background:none;border:0;color:var(--parch-dim);
  font-size:1.9rem;line-height:1;cursor:pointer;padding:4px 8px;
}
.modal-x:hover{color:var(--gold-lt)}
.modal-head{text-align:center;margin-bottom:18px}
.modal-logo{width:168px;margin:0 auto 10px;opacity:.95}
.modal-title{font-family:var(--display);font-weight:400;font-size:1.5rem;margin:0;color:#f6ecd6}

.tabs{display:flex;gap:4px;margin-bottom:20px;border-bottom:1px solid var(--line)}
.tab{
  flex:1;background:none;border:0;cursor:pointer;
  font-family:var(--display);text-transform:uppercase;letter-spacing:.07em;
  font-size:.85rem;color:var(--parch-dim);padding:.85em .4em;
  border-bottom:2px solid transparent;margin-bottom:-1px;
}
.tab[aria-selected="true"]{color:var(--gold-lt);border-bottom-color:var(--gold)}
.tab:hover{color:var(--parch)}

.pane{display:grid;gap:16px}
.pane[hidden]{display:none}
.pane label{display:grid;gap:6px;font-size:.92rem;color:var(--parch-dim);letter-spacing:.02em}
.pane label[hidden]{display:none}   /* beats the display:grid above */
.pane .opt{color:#6d7a85}
.pane input{
  font-family:var(--body);font-size:1.02rem;color:var(--parch);
  background:rgba(3,10,18,.7);
  border:1px solid rgba(201,162,39,.28);border-radius:var(--r);
  padding:.66em .8em;width:100%;
}
.pane input:focus{border-color:var(--gold);outline:none;box-shadow:0 0 0 3px rgba(201,162,39,.16)}
.pane input[aria-invalid="true"]{border-color:var(--danger)}
.pane small{color:#6d7a85;font-size:.8rem;line-height:1.45}
.pane small.warn-note{color:#8a7d5f}
.swap{margin:0;text-align:center;font-size:.92rem;color:var(--parch-dim)}

.alert{margin:0;padding:.7em .9em;border-radius:var(--r);font-size:.92rem;line-height:1.5}
.alert[hidden]{display:none}
.alert-err{background:rgba(224,104,92,.12);border:1px solid rgba(224,104,92,.45);color:#f0a79f}
.alert-ok{background:rgba(121,180,122,.12);border:1px solid rgba(121,180,122,.45);color:#a7d3a8}
.alert-warn{background:rgba(201,162,39,.1);border:1px solid rgba(201,162,39,.4);color:var(--gold-lt);margin-bottom:16px}

.btn.is-busy{opacity:.6;pointer-events:none}

@media (max-width:760px){
  .wheel{width:210px;right:-70px;opacity:.098}   /* was .13 × .75 */
  .rope-rule::before{inset:4px 5% auto 5%}
}

@media (max-width:520px){
  body{font-size:18px}
  .modal-card{padding:24px 20px 26px}
  .hero{padding:100px 0 70px}
  /* the tear reads as damage at this width, and the tilt costs gutter */
  .sheet{transform:none;padding:32px 24px 34px}
  .wheel{width:170px;right:-58px;opacity:.078}   /* was .13 × .6 */
  .feature-list li{padding-left:29px}
  .feature-list li::before{width:18px;height:18px}
}

/* ---------------- document pages ---------------- */
/* terms.html / privacy.html (added 2026-08-12). New class names only —
   nothing above is modified, so the landing page is untouched. These pages
   have no hero, so their <header> ships `is-stuck` in the markup and the
   first band pays for the fixed bar's height itself.
   Long-form prose deliberately stays on the deck band rather than on the
   parchment .sheet: the sheet's torn clip-path is cut for a short blurb
   and eats the edges of a page this tall. */
.doc-top{padding-top:calc(74px + clamp(48px,7vw,88px))}
.doc{max-width:72ch}
.doc h3{
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.16rem,2.2vw,1.4rem);
  color:#f6ecd6;margin:2.3em 0 .55em;letter-spacing:.01em;
}
.doc p{margin:0 0 1.05em;color:var(--parch-dim)}
.doc ul{margin:0 0 1.5em;padding-left:1.15em}
.doc li{margin-bottom:.55em;color:var(--parch-dim)}
.doc li::marker{color:rgba(201,162,39,.65)}
.doc strong{color:var(--parch);font-weight:600}
.doc a{color:var(--gold-lt);text-decoration:underline;text-underline-offset:3px}
.doc a:hover{color:#f4e2a4}
.doc .lede{margin-bottom:.6em}
.doc-meta{margin:0 0 2.2em;color:#7d8b96;font-size:.9rem}

/* narrow screens: the tables scroll in their own box, never the page */
.doc-scroll{overflow-x:auto;margin:0 0 1.8em}
.doc-table{width:100%;min-width:420px;border-collapse:collapse;font-size:.95rem}
.doc-table th,.doc-table td{
  text-align:left;vertical-align:top;padding:.75em .85em;
  border-bottom:1px solid var(--line);
}
.doc-table th{
  font-family:var(--display);font-weight:400;
  text-transform:uppercase;letter-spacing:.07em;font-size:.78rem;
  color:var(--gold-lt);
}
.doc-table td{color:var(--parch-dim)}
.doc-table td:first-child{color:var(--parch);width:30%}
.doc-table tbody tr:last-child td{border-bottom:0}

/* the footer's own links show which page you are on */
.foot-links a[aria-current="page"]{color:var(--gold-lt)}

/* ---------------- admin ---------------- */
/* admin.html (added 2026-08-16). New class names only — nothing above is
   modified. Reuses .doc / .doc-scroll / .doc-table / .pane / .alert / .btn
   wholesale; what is left is only the handful of things a queue needs and a
   prose page does not. */

/* The sign-in form sits in a page-width column, so it needs a cap of its own —
   .pane inside .modal-card gets one from the card. */
.admin-signin{max-width:26rem;margin:0 0 2em}

.admin-bar{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  margin:0 0 1.4em;
}
.admin-bar .btn{padding:.45em 1em;font-size:.85rem}
.admin-count{flex:1 1 auto;color:var(--parch);font-family:var(--display);letter-spacing:.02em}

/* Usernames are the scannable column here, and they are short — the prose
   table's 30% first column leaves the decision buttons cramped. */
.admin-table td:first-child{width:auto;white-space:nowrap}
.admin-table td.admin-actions{width:1%;white-space:nowrap;text-align:right}
.admin-actions .btn{padding:.4em .9em;font-size:.82rem;margin-left:8px}

@media (max-width:560px){
  .admin-actions .btn{margin:2px 0 2px 6px}
}

/* ---------------- all-accounts list (added 2026-08-18) ---------------- */
/* The user register, under the queue. Same rule again: new names only, and it
   reuses .admin-bar / .admin-table / .doc-scroll wholesale — what follows is
   only the filter control and the pager, which the queue has no use for. */
.admin-accounts{margin:2.6em 0 0;padding-top:.4em;border-top:1px solid var(--line)}

/* Five columns of dates and statuses need more room than the queue's four, so
   this table is allowed to scroll sooner rather than crushing the last column. */
.admin-accounts .doc-table{min-width:760px}

/* Wraps, unlike the username column: "Approved · Banned permanently" is the
   long case and forcing it onto one line is what pushes the table wide. */
.admin-accounts .admin-table td:nth-child(3){white-space:normal;min-width:11rem}

/* The two date columns do NOT wrap. "Aug 18, 2026 01:40 PM" broken across three
   lines is unreadable as a timestamp and makes every row a different height, so
   the eye cannot scan the column — which is the entire job of a "last seen"
   column. Letting the table overflow into .doc-scroll instead is the better
   trade: horizontal scroll is a known gesture, a mangled date is not. */
.admin-accounts .admin-table td:nth-child(4),
.admin-accounts .admin-table td:nth-child(5),
.admin-accounts .admin-table th:nth-child(4),
.admin-accounts .admin-table th:nth-child(5){white-space:nowrap}

/* The temporary password, shown once (added 2026-08-18). Borrows .pane and
   .admin-secret from the enrolment panel — it is the same kind of object: a
   secret that exists on this page and nowhere else. */
.admin-reset{margin:0 0 1.6em;max-width:34rem}
.admin-reset[hidden]{display:none}
.admin-reset h4{
  font-family:var(--display);font-weight:400;
  font-size:1rem;letter-spacing:.04em;
  color:var(--gold-lt);margin:0 0 .6em;
}
.admin-reset small{display:block;margin-top:.55em}

.admin-filter{
  display:flex;align-items:center;gap:8px;
  font-size:.85rem;color:var(--parch-dim);
}
.admin-filter select{
  background:rgba(0,0,0,.25);color:var(--parch);
  border:1px solid var(--line);border-radius:3px;
  padding:.4em .6em;font:inherit;font-size:.85rem;
}

/* The pager sits BELOW its table, so it loses .admin-bar's bottom margin and
   takes a top one instead. */
.admin-pager{margin:0 0 1.4em}

/* A disabled pager button stays in place rather than disappearing: buttons
   that come and go move the two that remain, and the target under the cursor
   changes between clicks. */
.admin-pager .btn:disabled{opacity:.4;pointer-events:none}

/* ---------------- two-factor (added 2026-08-17) ---------------- */
/* Again new names only. The verify step is the sign-in form in another guise,
   so it borrows .pane wholesale and only wants the same width cap. */
.admin-mfa{max-width:26rem;margin:0 0 2em}
.admin-mfa input:disabled{opacity:.5}

/* Enrolment sits under the queue, not beside it — it is a once-ever errand,
   and the rule keeps it from reading as another part of the queue. */
.admin-enroll{margin:2.6em 0 0;padding-top:.4em;border-top:1px solid var(--line)}
.admin-enroll[hidden]{display:none}
.admin-enroll-steps{max-width:34rem;margin-top:1.2em}
.admin-step h4{
  font-family:var(--display);font-weight:400;
  font-size:1rem;letter-spacing:.04em;
  color:var(--gold-lt);margin:0 0 .6em;
}
.admin-step small{display:block;margin-top:.55em}
.admin-btnrow{display:flex;flex-wrap:wrap;gap:10px;margin:.7em 0 0}
.admin-btnrow .btn{padding:.5em 1.1em;font-size:.85rem}
.admin-btnrow[hidden]{display:none}

/* The secret is typed by hand into a phone, so it is set wide and monospaced
   and shown exactly as issued — no grouping, because a space pasted into an
   authenticator that does not strip it is a fault nobody would diagnose. */
.admin-secret,.admin-codes{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Courier New",monospace;
  letter-spacing:.06em;
}
.admin-secret{font-size:1.02rem;color:var(--gold-lt)}
.admin-codes{
  font-size:.95rem;line-height:1.6;color:var(--parch);
  background:rgba(3,10,18,.7);
  border:1px solid rgba(201,162,39,.28);border-radius:var(--r);
  padding:.66em .8em;width:100%;resize:vertical;
}
.admin-codes:focus{border-color:var(--gold);outline:none;box-shadow:0 0 0 3px rgba(201,162,39,.16)}
