/* ═══════════════════════════════════════════════════════════════════════════════════
   POSTER.CSS — the one statement of the PlayerStory poster grammar.

   Every surface is drawn as a celebration poster: parchment stock, inscriptional
   capitals, a gold keyline, one illustrated plate. This file declares the palette,
   the faces and the ornaments ONCE. The per-game theme files that load after it
   (chess-theme.css / civ-theme.css / proto/proto.css) bind their own long-standing
   token names to these values — which is why no page markup had to change.

   Load order on every page:  poster.css  ->  <game>-theme.css  ->  the page's <style>

   Three theme states, not two. An explicit choice stamps data-theme on <html>; the
   default "system" setting stamps nothing and is separated only by prefers-color-scheme.
   Never give a colour its only definition inside a media or [data-theme] block.
   ═══════════════════════════════════════════════════════════════════════════════════ */

/* Cinzel & Playfair Display — SIL Open Font License 1.1. Self-hosted on purpose: a
   font CDN is a third party in the render path of every page we own. */
@font-face{font-family:"Cinzel";font-style:normal;font-weight:400;font-display:swap;
  src:url(/fonts/cinzel-400.woff2) format("woff2")}
@font-face{font-family:"Playfair Display";font-style:normal;font-weight:400;font-display:swap;
  src:url(/fonts/playfair-400.woff2) format("woff2")}
@font-face{font-family:"Playfair Display";font-style:italic;font-weight:400;font-display:swap;
  src:url(/fonts/playfair-italic.woff2) format("woff2")}

:root{
  /* ── the stock and the ink ──────────────────────────────────────────────────── */
  --ps-parch:#F6EEDC;      /* poster stock */
  --ps-stock2:#FBF6EA;     /* the lighter panel laid on it */
  --ps-ink:#153745;        /* deep petrol teal — display type; the chosen neutral */
  --ps-body:#3F5560;
  --ps-dim:#5A6A71;        /* captions, and they must still be READ: 4.87:1 on the
                              parchment. #7B8B92 measured 3.06:1 and failed AA. */
  --ps-line:#E0D2B6;
  --ps-line2:#CDBB98;      /* the second, darker rule of a double keyline */


/* Every colour in this light palette is set to clear WCAG AA (4.5:1) both on the bare
   parchment AND on the 12% tint of itself that these pages use as a plate ground — that
   second case is the one that catches people out, and it is where the first pass failed.
   The hues are the poster's; only the value moved. Measured, not eyeballed:
     teal 5.17 / 4.53   gold 5.22 / 4.51   rose 5.27 / 4.50   coral 5.15 / 4.56
     good 5.22 / 4.51   warn 5.12 / 4.51   risk 5.35 / 4.52   violet 5.71 / 4.84
   The dark palette already measured well (gilt on ink is 10.5:1) and is unchanged. */
  /* ── the palette ────────────────────────────────────────────────────────────── */
  --ps-gold:#7F5D1D;       /* gold you can READ */
  --ps-gilt:#E9C877;       /* gold you can only decorate with */
  --ps-rose:#AC3660;       /* the ONE loud action, nowhere else */
  --ps-onRose:#FFF8EE;
  --ps-teal:#256D73;
  --ps-aqua:#5FBDB6;
  --ps-violet:#6A4E9C;
  --ps-coral:#A14A2D;

  /* ── meaning, kept deliberately apart from the palette, so that red never
        has to mean two things at once ──────────────────────────────────────────── */
  --ps-good:#346E4D; --ps-warn:#895A21; --ps-risk:#AD354F;

  --ps-shadow:0 1px 2px rgba(21,55,69,.05), 0 14px 40px -18px rgba(21,55,69,.30);
  --ps-edge:linear-gradient(99deg,rgba(201,154,46,.75) 8%,rgba(198,62,110,.55) 52%,rgba(106,78,156,.5) 100%);

  --ps-disp:"Cinzel","Trajan Pro",Optima,"Palatino Linotype",Palatino,Georgia,serif;
  --ps-edit:"Playfair Display",Didot,"Iowan Old Style",Georgia,serif;
  --ps-sans:ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
  --ps-mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace;
}

/* dark = the poster after the lamps are lit. Tokens only, never components. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --ps-parch:#101E26; --ps-stock2:#172B35; --ps-ink:#F4E9D3; --ps-body:#C4D2D6;
    --ps-dim:#8FA1AC; --ps-line:#26414D; --ps-line2:#345362;
    --ps-gold:#E9C877; --ps-gilt:#C99A2E; --ps-rose:#F07FA3; --ps-onRose:#16242C;
    --ps-teal:#6FC7C0; --ps-aqua:#3E8F92; --ps-violet:#A98BE0; --ps-coral:#F0916B;
    --ps-good:#63BC8C; --ps-warn:#DFA55C; --ps-risk:#F0808F;
    --ps-shadow:0 1px 2px rgba(0,0,0,.35), 0 18px 46px -20px rgba(0,0,0,.7);
    --ps-edge:linear-gradient(99deg,rgba(233,200,119,.7) 8%,rgba(240,127,163,.5) 52%,rgba(169,139,224,.45) 100%);
  }
}
:root[data-theme="dark"]{
  --ps-parch:#101E26; --ps-stock2:#172B35; --ps-ink:#F4E9D3; --ps-body:#C4D2D6;
  --ps-dim:#8FA1AC; --ps-line:#26414D; --ps-line2:#345362;
  --ps-gold:#E9C877; --ps-gilt:#C99A2E; --ps-rose:#F07FA3; --ps-onRose:#16242C;
  --ps-teal:#6FC7C0; --ps-aqua:#3E8F92; --ps-violet:#A98BE0; --ps-coral:#F0916B;
  --ps-good:#63BC8C; --ps-warn:#DFA55C; --ps-risk:#F0808F;
  --ps-shadow:0 1px 2px rgba(0,0,0,.35), 0 18px 46px -20px rgba(0,0,0,.7);
  --ps-edge:linear-gradient(99deg,rgba(233,200,119,.7) 8%,rgba(240,127,163,.5) 52%,rgba(169,139,224,.45) 100%);
}

/* ═══ the ornaments ═══════════════════════════════════════════════════════════════
   Opt-in classes. Nothing here restyles an existing element by itself, so adding
   this file to a page can never break that page's layout.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* a gold rule with a four-point star at its centre — the section divider */
.ps-rule{display:flex; align-items:center; gap:16px; margin:40px 0}
.ps-rule::before,.ps-rule::after{content:''; height:1px; flex:1;
  background:linear-gradient(90deg,transparent,var(--ps-line2) 22%,var(--ps-line2) 78%,transparent)}
.ps-rule::after{transform:scaleX(-1)}
.ps-rule i{color:var(--ps-gilt); font-style:normal; font-size:15px; line-height:1;
  letter-spacing:.5em; padding-left:.5em}
.ps-rule i::before{content:'\2726'}

/* the small-caps letterspaced label that opens every block */
.ps-eyebrow{font:400 10.5px/1 var(--ps-disp); letter-spacing:.3em; text-transform:uppercase;
  color:var(--ps-gold); padding-left:.3em; margin:0}
.ps-eyebrow.t{color:var(--ps-teal)} .ps-eyebrow.r{color:var(--ps-rose)}

/* inscriptional display type, and the editorial headline beside it */
.ps-display{font:400 clamp(28px,4vw,52px)/1.06 var(--ps-disp); letter-spacing:.03em;
  color:var(--ps-ink); margin:0; text-transform:uppercase; text-wrap:balance}
.ps-headline{font:400 clamp(24px,3.2vw,38px)/1.16 var(--ps-edit); color:var(--ps-ink);
  margin:0; letter-spacing:-.012em; text-wrap:balance}
.ps-headline em{font-style:italic; color:var(--ps-rose)}
.ps-figure{font:400 var(--fs,30px)/1 var(--ps-disp); color:var(--ps-ink);
  font-variant-numeric:tabular-nums}

/* a plate — the panel with a double keyline, the poster's own device */
.ps-plate{background:var(--ps-stock2); border:1px solid var(--ps-line2); border-radius:14px;
  padding:22px 24px; position:relative;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ps-stock2) 70%,var(--ps-parch)),
             inset 0 0 0 2px var(--ps-line)}

/* art always hangs in a mount with a gold keyline and a museum plaque under it */
.ps-mount{border:1px solid var(--ps-line2); border-radius:14px; padding:9px;
  background:var(--ps-stock2); box-shadow:inset 0 0 0 1px var(--ps-line)}
.ps-mount>.art{border-radius:8px; background-size:cover; background-position:center;
  aspect-ratio:1/1; display:block}
.ps-mount>.plaque{display:flex; align-items:center; gap:9px; padding:9px 4px 2px;
  font:400 10.5px/1 var(--ps-disp); letter-spacing:.24em; text-transform:uppercase;
  color:var(--ps-dim)}
.ps-mount>.plaque b{margin-left:auto; letter-spacing:.14em; color:var(--ps-ink); font-weight:400}

/* the eight plates, addressable by name */
.ps-art-hero{background-image:url(/art/poster/hero.webp)}
.ps-art-chess{background-image:url(/art/poster/chess.webp)}
.ps-art-civ{background-image:url(/art/poster/civ.webp)}
.ps-art-moba{background-image:url(/art/poster/moba.webp)}
.ps-art-cards{background-image:url(/art/poster/cards.webp)}
.ps-art-strategy{background-image:url(/art/poster/strategy.webp)}
.ps-art-couch{background-image:url(/art/poster/couch.webp)}
.ps-art-crest{background-image:url(/art/poster/crest.webp)}

/* the mark */
.ps-crest{width:var(--sz,34px); height:var(--sz,34px); flex:0 0 auto; display:inline-block;
  background:url(/art/poster/crest.webp) center/contain no-repeat}

/* the one loud action */
.ps-cta{display:inline-flex; align-items:center; gap:9px; border:1px solid transparent;
  background:var(--ps-rose); color:var(--ps-onRose); border-radius:999px; padding:12px 24px;
  font:600 15px var(--ps-sans); cursor:pointer; text-decoration:none}
.ps-cta:hover{filter:brightness(1.06)}
.ps-cta-glow{position:relative; display:inline-block}
.ps-cta-glow::before{content:''; position:absolute; inset:5px 9px -7px; border-radius:999px;
  background:var(--ps-edge); filter:blur(15px); opacity:.6}
.ps-cta-glow>.ps-cta{position:relative}

/* the theme switch, injected by poster.js into whatever bar the page already has */
.ps-themer{display:inline-flex; align-items:center; gap:8px; padding:8px 14px 7px;
  border-radius:999px; cursor:pointer; background:transparent; color:var(--ps-ink);
  border:1px solid var(--ps-line2);
  font:400 10.5px/1 var(--ps-disp); letter-spacing:.24em; text-transform:uppercase;
  padding-left:15px}
.ps-themer:hover{border-color:var(--ps-gold)}
.ps-themer .gl{font-size:12px; line-height:1; letter-spacing:0; color:var(--ps-gold)}

/* the warm field the stock is printed on — opt in on landing surfaces only */
.ps-field{background:
  radial-gradient(58% 46% at 4% 0%, color-mix(in srgb,var(--ps-gilt) 34%,transparent), transparent 70%),
  radial-gradient(46% 42% at 96% 2%, color-mix(in srgb,var(--ps-rose) 16%,transparent), transparent 72%),
  radial-gradient(64% 56% at 80% 92%, color-mix(in srgb,var(--ps-teal) 18%,transparent), transparent 72%)}

:where(a,button,[tabindex]):focus-visible{outline:2px solid var(--ps-rose); outline-offset:3px;
  border-radius:4px}

/* ═══ the app shell ═══════════════════════════════════════════════════════════════
   The chrome the newer pages are built from. Older pages keep their own bars; these
   exist so that anything built from here on is consistent by construction.
   ═══════════════════════════════════════════════════════════════════════════════ */
.ps-page{margin:0; background:var(--ps-parch); color:var(--ps-body);
  font:15.5px/1.62 var(--ps-sans); -webkit-font-smoothing:antialiased; min-height:100vh}

.ps-bar{display:flex; align-items:center; gap:26px; padding:16px 30px;
  border-bottom:1px solid var(--ps-line); background:var(--ps-parch);
  position:sticky; top:0; z-index:40}
.ps-bar .mark{display:flex; align-items:center; gap:10px; text-decoration:none;
  font:400 18px/1 var(--ps-disp); letter-spacing:.13em; text-transform:uppercase;
  color:var(--ps-ink)}
.ps-bar nav{display:flex; gap:20px; flex-wrap:wrap}
.ps-bar nav a{color:var(--ps-body); text-decoration:none; font-size:13.5px}
.ps-bar nav a:hover{color:var(--ps-ink)}
.ps-bar nav a[aria-current="page"]{color:var(--ps-ink); box-shadow:inset 0 -1px 0 0 var(--ps-gold)}
.ps-bar .right{margin-left:auto; display:flex; align-items:center; gap:12px}

.ps-wrap{max-width:1120px; margin:0 auto; padding:34px 24px 90px;
  display:flex; flex-direction:column; gap:22px}
.ps-hero{padding:52px 24px 34px; max-width:1120px; margin:0 auto;
  display:flex; flex-direction:column; gap:16px}

.ps-row{display:flex; align-items:center; gap:13px; padding:13px 15px;
  background:var(--ps-parch); border:1px solid var(--ps-line); border-radius:9px}
.ps-row+.ps-row{margin-top:8px}
.ps-row .t1{color:var(--ps-ink); font-weight:600; font-size:14.5px}
.ps-row .t2{color:var(--ps-dim); font-size:12.5px}
.ps-row .end{margin-left:auto; text-align:right; white-space:nowrap}
.ps-stack{display:flex; flex-direction:column; gap:8px}

.ps-chip{display:inline-flex; align-items:center; gap:6px; border-radius:999px;
  padding:4px 11px; font:600 11.5px/1.5 var(--ps-sans); border:1px solid var(--ps-line2);
  color:var(--ps-body); background:var(--ps-parch); text-decoration:none}
.ps-chip.gold{color:var(--ps-gold); border-color:color-mix(in srgb,var(--ps-gold) 45%,transparent); background:color-mix(in srgb,var(--ps-gold) 10%,transparent)}
.ps-chip.good{color:var(--ps-good); border-color:color-mix(in srgb,var(--ps-good) 42%,transparent); background:color-mix(in srgb,var(--ps-good) 10%,transparent)}
.ps-chip.risk{color:var(--ps-risk); border-color:color-mix(in srgb,var(--ps-risk) 42%,transparent); background:color-mix(in srgb,var(--ps-risk) 10%,transparent)}
.ps-chip.warn{color:var(--ps-warn); border-color:color-mix(in srgb,var(--ps-warn) 42%,transparent); background:color-mix(in srgb,var(--ps-warn) 10%,transparent)}
.ps-chip.teal{color:var(--ps-teal); border-color:color-mix(in srgb,var(--ps-teal) 42%,transparent); background:color-mix(in srgb,var(--ps-teal) 10%,transparent)}
.ps-chip.violet{color:var(--ps-violet); border-color:color-mix(in srgb,var(--ps-violet) 42%,transparent); background:color-mix(in srgb,var(--ps-violet) 10%,transparent)}
.ps-chip.live::before{content:''; width:6px; height:6px; border-radius:50%; background:currentColor}

.ps-meter{height:8px; border-radius:999px; overflow:hidden;
  background:color-mix(in srgb,var(--ps-ink) 9%,transparent)}
.ps-meter>i{display:block; height:100%; border-radius:999px; background:var(--c,var(--ps-teal))}

.ps-grid{display:grid; gap:16px; grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
.ps-grid.two{grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
.ps-spread{display:flex; align-items:center; gap:12px; flex-wrap:wrap}
.ps-tiny{font-size:12.5px; color:var(--ps-dim); margin:0}
.ps-lede{margin:0; max-width:62ch; font-size:16px; color:var(--ps-body)}

/* a pennant — a game or a piece of content, hung from its own colour band */
.ps-pennant{background:var(--ps-stock2); border:1px solid var(--ps-line2); border-radius:14px;
  overflow:hidden; display:flex; flex-direction:column; text-decoration:none;
  box-shadow:inset 0 0 0 1px var(--ps-line)}
.ps-pennant:hover{border-color:var(--ps-gold)}
.ps-pennant>.top{height:5px; background:var(--c,var(--ps-teal))}
.ps-pennant>.art{aspect-ratio:16/10; background-size:cover; background-position:center;
  margin:9px 9px 0; border-radius:8px}
.ps-pennant>.body{padding:13px 16px 17px; display:flex; flex-direction:column; gap:6px}
.ps-pennant .nm{font:400 16px/1.2 var(--ps-disp); letter-spacing:.09em; text-transform:uppercase;
  color:var(--ps-ink)}
.ps-pennant .st{font-size:12.5px; color:var(--ps-dim)}
.ps-pennant .go{margin-top:6px; font:600 12px var(--ps-sans); color:var(--ps-rose)}

@media (max-width:640px){
  .ps-bar{gap:14px; padding:12px 16px} .ps-bar nav{display:none}
  .ps-wrap,.ps-hero{padding-left:16px; padding-right:16px}
}
@media (prefers-reduced-motion:no-preference){
  .ps-plate,.ps-pennant{transition:border-color .2s ease}
}

/* chess-theme gives a bare h1 a decorative mark, which is right on a tool page and wrong
   on a poster headline. Class beats element, so this holds regardless of load order. */
h1.ps-display::before, h2.ps-display::before,
h1.ps-headline::before, h2.ps-headline::before{content:none; display:none}
/* a chip must never break its own label across two lines */
.ps-chip{white-space:nowrap}

/* ═══════════════════════════════════════════════════════════════════════════════════
   THE IN-APP LAYER  —  body.ps-app only
   ═══════════════════════════════════════════════════════════════════════════════════
   The marketing surfaces (chess-home, civ-home, lol-home, the hub) keep their own
   art-directed layouts; they are the shop window and they are already right. THIS layer
   is for the screens a signed-in player actually works in, and it turns the poster from
   a palette into a structure: every card becomes a printed plate with a double keyline,
   every section opens on an inscriptional eyebrow, figures are set in the display face,
   and the one loud action is the only saturated thing on screen.

   It deliberately restyles the class names those pages ALREADY use — .card, .pill,
   .eyebrow, .stat, .num — rather than asking 37 pages to change their markup.
   ═══════════════════════════════════════════════════════════════════════════════════ */

body.ps-app{background:var(--ps-parch); color:var(--ps-body)}

/* ── the plate. 212 .card instances across the app become printed plates. ─────────── */
body.ps-app .card{
  background:var(--ps-stock2);
  border:1px solid var(--ps-line2);
  border-radius:14px;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ps-stock2) 70%,var(--ps-parch)),
             inset 0 0 0 2px var(--ps-line);
}
/* a plate inside a plate is a row, not a second frame — otherwise the keylines stack
   into a moiré of gold hairlines. */
body.ps-app .card .card{
  box-shadow:none; border-radius:9px; border-color:var(--ps-line);
  background:var(--ps-parch);
}

/* ── type ─────────────────────────────────────────────────────────────────────────── */
body.ps-app h1{font-family:var(--ps-disp); font-weight:400; letter-spacing:.03em;
  color:var(--ps-ink)}
body.ps-app h2, body.ps-app h3{font-family:var(--ps-edit); font-weight:400; color:var(--ps-ink)}
body.ps-app h4{font-family:var(--ps-disp); font-weight:400; letter-spacing:.16em;
  text-transform:uppercase; font-size:12px; color:var(--ps-ink)}

/* the app already has an .eyebrow; make it inscriptional */
body.ps-app .eyebrow{font-family:var(--ps-disp); font-weight:400; letter-spacing:.28em;
  text-transform:uppercase; color:var(--ps-gold); padding-left:.28em}

/* figures are set in the display face and lined up — this is a coaching product, the
   numbers are the argument */
body.ps-app .num, body.ps-app .stat, body.ps-app .v{
  font-family:var(--ps-disp); font-weight:400; font-variant-numeric:tabular-nums;
  color:var(--ps-ink)}
body.ps-app .small{font-size:12.8px}
body.ps-app .muted, body.ps-app .dim, body.ps-app .sub{color:var(--ps-dim)}

/* ── pills and chips ──────────────────────────────────────────────────────────────── */
body.ps-app .pill{border-radius:999px; border:1px solid var(--ps-line2);
  background:var(--ps-parch); color:var(--ps-body); font-weight:600; white-space:nowrap}
body.ps-app .pill.accent, body.ps-app .accent{color:var(--ps-rose)}

/* ── actions: exactly one loud thing per screen ───────────────────────────────────── */
body.ps-app .btn{border-radius:999px; border:1px solid var(--ps-line2);
  background:var(--ps-parch); color:var(--ps-ink); font-family:var(--ps-sans); font-weight:600}
body.ps-app .btn:hover{border-color:var(--ps-gold)}
body.ps-app .btn.primary, body.ps-app .btn.cta, body.ps-app .primary{
  background:var(--ps-rose); color:var(--ps-onRose); border-color:transparent}
body.ps-app .btn.ghost, body.ps-app .ghost{background:transparent; color:var(--ps-body)}

/* ── the app bar wears the crest and the inscriptional wordmark ───────────────────── */
body.ps-app .appbar, body.ps-app .phead{
  background:var(--ps-parch); border-bottom:1px solid var(--ps-line)}
body.ps-app .appbar .brand, body.ps-app .appbar .logo, body.ps-app .brand{
  font-family:var(--ps-disp); font-weight:400; letter-spacing:.13em; text-transform:uppercase;
  color:var(--ps-ink)}

/* ── a section break is a gold rule with a star, the same one the poster uses ─────── */
body.ps-app hr{border:0; height:1px; margin:34px 0;
  background:linear-gradient(90deg,transparent,var(--ps-line2) 22%,var(--ps-line2) 78%,transparent);
  position:relative; overflow:visible}
body.ps-app hr::after{content:'\2726'; position:absolute; top:50%; left:50%;
  transform:translate(-50%,-50%); background:var(--ps-parch); padding:0 12px;
  color:var(--ps-gilt); font-size:13px; line-height:1}

/* ── inputs sit in the stock, not on it ───────────────────────────────────────────── */
body.ps-app input, body.ps-app select, body.ps-app textarea{
  background:var(--ps-parch); border:1px solid var(--ps-line2); color:var(--ps-ink);
  border-radius:9px; font-family:var(--ps-sans)}
body.ps-app input:focus, body.ps-app select:focus, body.ps-app textarea:focus{
  border-color:var(--ps-gold); outline:none}

/* ── tables read as a ledger ──────────────────────────────────────────────────────── */
body.ps-app table{border-collapse:collapse}
body.ps-app th{font-family:var(--ps-disp); font-weight:400; letter-spacing:.14em;
  text-transform:uppercase; font-size:11px; color:var(--ps-dim); text-align:left;
  border-bottom:1px solid var(--ps-line2); padding-bottom:7px}
body.ps-app td{border-bottom:1px solid var(--ps-line); padding:9px 0;
  font-variant-numeric:tabular-nums}

/* ── the illustrated plate, for the screens whose mockup carries art ──────────────── */
body.ps-app .ps-hang{border:1px solid var(--ps-line2); border-radius:14px; padding:9px;
  background:var(--ps-stock2); box-shadow:inset 0 0 0 1px var(--ps-line)}
body.ps-app .ps-hang>.art{border-radius:8px; background-size:cover; background-position:center;
  aspect-ratio:16/9; display:block}
body.ps-app .ps-hang>.plaque{display:flex; gap:9px; padding:9px 4px 2px;
  font:400 10.5px/1 var(--ps-disp); letter-spacing:.24em; text-transform:uppercase;
  color:var(--ps-dim)}
body.ps-app .ps-hang>.plaque b{margin-left:auto; letter-spacing:.14em; color:var(--ps-ink);
  font-weight:400}

/* the empty state is a plate too — an app with no data yet should still look composed */
body.ps-app .empty{background:var(--ps-stock2); border:1px solid var(--ps-line2);
  border-radius:14px; color:var(--ps-dim);
  box-shadow:inset 0 0 0 1px var(--ps-line)}

/* ═══════════════════════════════════════════════════════════════════════════════════
   THE COMPOSITION  —  body.ps-app
   ═══════════════════════════════════════════════════════════════════════════════════
   Colour and type alone did not make the app read as the poster set; the rhythm is half
   of what makes those plates look printed. These are the METRICS lifted straight from
   the mockup stylesheet — the measure, the plate padding, the row height, the type
   scale, the bar — so a shipped screen and its mockup are set to the same grid.
   ═══════════════════════════════════════════════════════════════════════════════════ */

/* the measure. A poster has margins; a dashboard crammed to the viewport edge never
   reads as one. */
body.ps-app .wrap, body.ps-app .pcol, body.ps-app main > .container{
  max-width:1120px; margin-inline:auto; padding:34px 30px 80px}

/* plates breathe, and they are spaced by a consistent gap rather than by whatever
   margin each card happened to carry */
body.ps-app .card{padding:22px 24px; margin-block:0 16px}
body.ps-app .card > :first-child{margin-top:0}
body.ps-app .card > :last-child{margin-bottom:0}

/* a plate opens on an eyebrow, then the headline. This is the single most recognisable
   move in the set, so it gets real spacing rather than being crammed. */
body.ps-app .eyebrow{display:block; font-size:10.5px; margin:0 0 12px}
body.ps-app .card > h2, body.ps-app .card > h3{margin:0 0 10px; letter-spacing:-.008em}

/* the type scale */
body.ps-app h1{font-size:clamp(30px,3.6vw,46px); line-height:1.08; margin:0 0 10px}
body.ps-app h2{font-size:clamp(22px,2.4vw,30px); line-height:1.2}
body.ps-app h3{font-size:19px; line-height:1.3}
body.ps-app .lede, body.ps-app .sub{max-width:64ch; font-size:15.5px}

/* figures carry a label beneath them, at eyebrow scale — the mockups' stat block */
body.ps-app .num, body.ps-app .stat{font-size:var(--fs,28px); line-height:1}

/* rows: one height, one radius, and a severity rule on the left where the page already
   marks priority. Colour on the rail, never on the row's ground. */
body.ps-app .row, body.ps-app .ev, body.ps-app .item{
  padding:12px 14px; border-radius:9px; gap:13px}
body.ps-app .prio, body.ps-app .fix, body.ps-app .drill{
  border-left:3px solid var(--accent); border-radius:0 9px 9px 0}
body.ps-app .prio.urgent, body.ps-app .prio:first-of-type{border-left-color:var(--loss)}

/* chips */
body.ps-app .pill, body.ps-app .chip, body.ps-app .badge{
  padding:4px 11px; font-size:11.5px; line-height:1.5}

/* the bar, set to the mockup's own metrics */
body.ps-app .appbar, body.ps-app .phead{padding:15px 30px; gap:26px}
body.ps-app .appbar .brand, body.ps-app .brand{font-size:18px; letter-spacing:.13em; gap:10px}

/* meters read as a printed rule, not a UI progress bar */
body.ps-app .meter, body.ps-app .bar-track, body.ps-app progress{
  height:8px; border-radius:999px;
  background:color-mix(in srgb,var(--ps-ink) 9%,transparent)}

/* the empty state is a composed plate, because a new account sees these first */
body.ps-app .empty{padding:28px 26px; text-align:center; font-size:14.5px}
body.ps-app .empty::before{content:'\2726'; display:block; color:var(--ps-gilt);
  font-size:15px; margin-bottom:10px}

@media (max-width:720px){
  body.ps-app .wrap, body.ps-app .pcol{padding:22px 16px 60px}
  body.ps-app .card{padding:18px 16px}
  body.ps-app .appbar, body.ps-app .phead{padding:12px 16px; gap:14px}
}
