/* ==========================================================================
   ui.css — the 2026-10 redesign layer.

   Loaded AFTER style.css so it can retune the shell and the landing page
   without rewriting 817 lines of working app CSS. Everything here is
   prefixed or scoped: the kiosk and token pages never load this file, so the
   dark booth is untouched.

   Rules carried over from the approved directions:
   - indigo is for actions only, never chrome decoration
   - type scale 32 / 28 / 16 / 14 (+12 for chips and tab labels)
   - one elevated surface per page
   - flat borders everywhere else
   ========================================================================== */

:root{
  --indigo:#4338CA;
  --indigo-deep:#3730a3;
  --indigo-soft:#c7d2fe;
  --indigo-wash:#eef2ff;
  --ink-strong:#1b1f24;
  --line-soft:#e5e9f0;
  --line-strong:#d3dae6;
  --canvas:#f8f9fc;
  --danger-ink:#b42318;
  --r-ctl:8px;
  --r-card:12px;
  --r-panel:16px;
  --shadow-card:0 1px 2px rgba(15,23,42,.06), 0 8px 24px rgba(15,23,42,.06);
  --ui-max:1120px;
  --ui-gutter:32px;

  /* Semantic surfaces. Every `background:#fff` in this file is a surface, so
     naming it is what makes a second palette possible at all. */
  --surface:#ffffff;
  --surface-sunken:#f1f3f7;
  /* The even-row stripe. One token, so the sticky first column can never
     drift from the stripe it is supposed to match. */
  --stripe:rgba(15,23,42,.03);
  /* Filled controls keep white text, so their fill cannot be the same value
     as the text accent once the palette inverts. */
  --indigo-solid:#4338CA;
  --on-accent:#ffffff;
  --warn-bg:#fef3c7;
  --warn-ink:#78350f;
  --warn-line:#fcd34d;
  --danger-wash:#fef2f2;
  --danger-line:#fca5a5;
}


/* --------------------------------------------------------------------------
   Dark theme
   Two selectors, one palette: an explicit choice, and the OS preference when
   the visitor left the toggle on "system". Light stays the default, so an
   account that never touches the toggle keeps the page it has today.
   -------------------------------------------------------------------------- */
[data-theme="dark"]{
  color-scheme:dark;
  --canvas:#0d1117;
  --surface:#161b23;
  --surface-sunken:#1b222c;
  --stripe:rgba(148,163,184,.06);
  --ink-strong:#e6edf6;
  --muted:#93a2b8;
  --line-soft:#242c38;
  --line-strong:#333d4d;
  --indigo:#7c83f5;
  --indigo-deep:#a5aaff;
  --indigo-soft:#3a3f7a;
  --indigo-wash:#1e2338;
  --danger-ink:#fca5a5;
  --danger-wash:#2a1a1a;
  --danger-line:#7f1d1d;
  --warn-bg:#3a2c12;
  --warn-ink:#fcd34d;
  --warn-line:#78500f;
  --shadow-card:0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.3);
  /* style.css keeps its own vocabulary; these make both layers agree. */
  --ink:#e6edf6;
  --line:#2b3442;
  --accent:#7c83f5;
  --bg:#0d1117;
  --info-bg:#12233a;
  --info-border:#1e3a5f;
}
@media (prefers-color-scheme: dark){
  [data-theme="system"]{
    color-scheme:dark;
    --canvas:#0d1117;
    --surface:#161b23;
    --surface-sunken:#1b222c;
    --stripe:rgba(148,163,184,.06);
    --ink-strong:#e6edf6;
    --muted:#93a2b8;
    --line-soft:#242c38;
    --line-strong:#333d4d;
    --indigo:#7c83f5;
    --indigo-deep:#a5aaff;
    --indigo-solid:#4f46e5;
    --indigo-soft:#3a3f7a;
    --indigo-wash:#1e2338;
    --danger-ink:#fca5a5;
    --danger-wash:#2a1a1a;
    --danger-line:#7f1d1d;
    --warn-bg:#3a2c12;
    --warn-ink:#fcd34d;
    --warn-line:#78500f;
    --shadow-card:0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.3);
    --ink:#e6edf6;
    --line:#2b3442;
    --accent:#7c83f5;
    --bg:#0d1117;
    --info-bg:#12233a;
    --info-border:#1e3a5f;
  }
}

/* Unclassed links fell back to the browser's #0000ee — 1.84:1 on a dark
   surface. Scoping this to .prose and .ui-col was not enough: receipt codes,
   seller names and "Laporkan" are bare <a> elements. A base rule covers them
   all; the header, button.link and .row-actions keep their own colour by
   specificity. */
a{color:var(--indigo)}
a:hover{color:var(--indigo-deep)}

/* --------------------------------------------------------------------------
   Shell — header
   The navy bar was the heaviest element on every page and carried no
   information. White surface, hairline, weight moved into the page content.
   -------------------------------------------------------------------------- */
header.nav{
  background:var(--surface);
  color:var(--ink-strong);
  padding:0;
  border-bottom:1px solid var(--line-soft);
  box-shadow:none;
}
header.nav .nav-in{
  max-width:var(--ui-max);
  margin:0 auto;
  padding:0 var(--ui-gutter);
  height:64px;
  display:flex;
  align-items:center;
  gap:24px;
}
header.nav .brand{
  color:var(--ink-strong);
  font-size:1rem;
  font-weight:700;
  gap:10px;
  min-height:0;
  padding:0;
  flex:0 0 auto;
}
header.nav .brand-mark{width:26px;height:26px}
header.nav nav{
  margin-left:auto;
  gap:22px;
  flex-wrap:nowrap;
}
header.nav .nav-main{gap:22px;flex-wrap:nowrap}
header.nav nav > a,
header.nav .nav-main a{
  color:var(--muted);
  font-size:.875rem;
  font-weight:600;
  min-height:0;
  padding:21px 0;
  position:relative;
  white-space:nowrap;
}
header.nav nav > a:hover,
header.nav .nav-main a:hover{color:var(--ink-strong)}
header.nav nav > a.active,
header.nav .nav-main a.active{
  color:var(--ink-strong);
  text-decoration:none;
  font-weight:600;
}
header.nav nav > a.active::after,
header.nav .nav-main a.active::after{
  content:"";
  position:absolute;
  left:0;right:0;bottom:14px;
  height:2px;
  background:var(--indigo);
  border-radius:2px;
}
header.nav .lang-switch{display:inline-flex;align-items:center;gap:5px;font-size:.875rem;font-weight:600}
header.nav .lang-switch a{
  color:var(--muted);
  padding:0;
  min-height:0;
  margin-left:0;
  font-weight:600;
}
header.nav .lang-switch a.active{color:var(--ink-strong)}
/* Theme switch: a menu, because three modes do not fit a one-row bar on a
   phone. The summary is a 44px target that shows the current state. */
header.nav .theme-switch{position:relative;display:inline-flex;align-items:center}
header.nav .theme-switch > summary{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;min-width:44px;padding:0 8px;border-radius:8px;
  color:var(--muted);cursor:pointer;list-style:none;
}
header.nav .theme-switch > summary::-webkit-details-marker{display:none}
header.nav .theme-switch > summary:hover{color:var(--ink-strong);background:var(--surface-sunken)}
header.nav .theme-switch[open] > summary{color:var(--ink-strong)}
header.nav .theme-panel{
  position:absolute;right:0;top:calc(100% + 6px);z-index:60;
  min-width:11rem;padding:6px;display:flex;flex-direction:column;gap:2px;
  background:var(--surface);border:1px solid var(--line-soft);
  border-radius:var(--r-card);box-shadow:var(--shadow-card);
}
header.nav .theme-panel a{
  display:flex;align-items:center;min-height:40px;padding:0 12px;
  border-radius:8px;color:var(--ink-strong);font-size:.875rem;font-weight:600;
  text-decoration:none;
}
header.nav .theme-panel a:hover{background:var(--surface-sunken)}
header.nav .theme-panel a.active{background:var(--indigo-wash);color:var(--indigo-deep)}

/* The credit chip is data, not chrome: quiet wash, tabular figures. */
header.nav .credit-chip{
  background:var(--indigo-wash);
  color:var(--indigo-deep);
  border-radius:999px;
  padding:6px 12px;
  font-size:.875rem;
  font-weight:600;
  font-variant-numeric:tabular-nums;
  text-decoration:none;
}
header.nav details.menu summary{
  min-height:0;
  padding:8px 12px;
  border:1px solid var(--line-strong);
  border-radius:var(--r-ctl);
  color:var(--ink-strong);
  font-size:.875rem;
  font-weight:600;
}
header.nav details.menu .menu-panel a{color:var(--ink-strong);font-size:.875rem}
header.nav button.link{color:var(--muted);font-size:.875rem}
/* Ghost "Masuk" — 40px, hairline, ink text. */
header.nav .nav-cta{
  min-height:40px;
  padding:0 14px;
  border:1px solid var(--line-strong);
  border-radius:var(--r-ctl);
  color:var(--ink-strong);
  font-size:.875rem;
  font-weight:600;
  display:inline-flex;
  align-items:center;
  white-space:nowrap;
}
header.nav .nav-cta:hover{border-color:var(--ink-strong)}

@media (max-width:760px){
  header.nav{flex-wrap:nowrap;padding:0}
  header.nav .nav-in{height:56px;padding:0 20px;gap:12px}
  /* Mobile header: brand + one action. The primary links live in the tab
     bar for a signed-in user and in the footer for a visitor. The
     :not(.has-user) selectors are needed to beat the older 640px rules in
     style.css, which re-showed the links for a visitor. */
  header.nav .nav-main,
  header.nav:not(.has-user) .nav-main,
  header.nav .lang-switch,
  header.nav:not(.has-user) .lang-switch,
  header.nav .credit-chip{display:none}
  /* The menu button stays. Hiding it here removed the only route to Profile,
     Plan, Referrals, Help, the language switch and Sign out on a portrait
     phone — the tab bar carries four destinations and none of those. */
  /* The help link is a direct child of nav (not .nav-main), so it needs its
     own rule or it survives and crowds the 56px bar. It is in the footer. */
  header.nav nav > a:not(.nav-cta){display:none}
  header.nav nav{margin-left:auto;gap:8px;overflow:visible;flex-wrap:nowrap}
  header.nav .nav-cta{margin-left:auto}

  /* The menu is a 44px icon target here, and its panel is anchored to the
     viewport edge so it cannot overflow a narrow screen. */
  header.nav details.menu{margin-left:auto}
  header.nav details.menu summary{
    min-width:44px;min-height:44px;padding:0 10px;
    display:inline-flex;align-items:center;justify-content:center;
  }
  header.nav details.menu .menu-panel{
    right:0;left:auto;min-width:min(15rem,calc(100vw - 32px));
  }
}

/* --------------------------------------------------------------------------
   Shell — footer
   -------------------------------------------------------------------------- */
footer.muted{
  max-width:none;
  margin:0;
  padding:0;
  border-top:1px solid var(--line-soft);
  color:var(--muted);
  font-size:.875rem;
}
footer.muted .footer-in{
  max-width:var(--ui-max);
  margin:0 auto;
  padding:32px var(--ui-gutter);
  display:flex;
  flex-wrap:wrap;
  gap:10px 24px;
  align-items:center;
  justify-content:space-between;
}
footer.muted .footer-links{display:inline-flex;flex-wrap:wrap;gap:4px 6px}
footer.muted .footer-links a{color:var(--muted);text-decoration:none}
footer.muted .footer-links a:hover{color:var(--indigo)}

/* --------------------------------------------------------------------------
   Shell — bottom tab bar (signed-in only, unchanged in behaviour)
   -------------------------------------------------------------------------- */
nav.tabbar{
  background:var(--surface);
  border-top:1px solid var(--line-soft);
  height:56px;
  padding-bottom:env(safe-area-inset-bottom);
  /* Sticky, not fixed: a fixed bar sits on top of the footer links and the
     last row of every table. Sticky keeps it in flow, so it pins to the
     viewport bottom while scrolling and lands above the footer at the end. */
  position:sticky;
  bottom:0;
  z-index:50;
  display:flex;
}
nav.tabbar a{
  flex:1;
  display:flex;
  align-items:center;
  justify-content:center;
  color:var(--muted);
  font-size:.75rem;
  font-weight:600;
  text-decoration:none;
}
nav.tabbar a.active{color:var(--indigo)}
@media (min-width:761px){nav.tabbar{display:none}}

/* --------------------------------------------------------------------------
   Page canvas
   -------------------------------------------------------------------------- */
main{
  max-width:var(--ui-max);
  margin:0 auto;
  padding:0 var(--ui-gutter);
}
@media (max-width:760px){
  /* The gutter token drives the hero's negative margin too, so it has to
     change in one place — a 32px negative margin against 20px padding is
     what pushed the page 12px sideways. */
  :root{--ui-gutter:20px}
  main{padding:0 var(--ui-gutter)}
  .hero{margin:0 calc(-1 * var(--ui-gutter));padding:0 var(--ui-gutter)}
}

/* Shared measure. Prose was running 116 characters per line at 960px. */
.ui-prose{max-width:68ch;font-size:1rem;line-height:1.65}
.ui-prose p{margin:0 0 14px}
.ui-prose p:last-child{margin-bottom:0}

/* --------------------------------------------------------------------------
   Landing — hero
   One elevated surface on the page: this one.
   -------------------------------------------------------------------------- */
.hero{
  background:var(--canvas);
  border-top:2px solid var(--indigo);
  margin:0 calc(-1 * var(--ui-gutter));
  padding:0 var(--ui-gutter);
  display:grid;
  grid-template-columns:1.02fr .98fr;
  gap:56px;
  align-items:center;
  min-height:440px;
}
.hero-copy{padding:56px 0 64px}
.hero h1{
  font-size:2rem;
  line-height:1.22;
  letter-spacing:-.015em;
  margin:16px 0 18px;
  max-width:20ch;
  color:var(--ink-strong);
}
.hero .lede{
  color:var(--muted);
  font-size:1rem;
  line-height:1.6;
  max-width:56ch;
  margin:0;
}
.hero .fair-play{
  display:inline-block;
  background:var(--indigo-wash);
  border:0;
  color:var(--indigo-deep);
  border-radius:999px;
  padding:5px 10px;
  font-size:.875rem;
  font-weight:600;
}
.hero .actions{
  display:flex;
  flex-wrap:wrap;
  gap:12px;
  margin:28px 0 0;
  align-items:center;
}
.hero .proof{
  display:flex;
  flex-wrap:wrap;
  gap:10px 28px;
  margin-top:26px;
  color:var(--muted);
  font-size:.875rem;
}
.hero .proof span{display:inline-flex;align-items:center;gap:8px}
.hero .proof span::before{
  content:"";
  width:6px;height:6px;
  border-radius:50%;
  background:var(--indigo-soft);
  border:1px solid var(--indigo);
}
/* Hero art: the capsule is the product, and the card inside it is the same
   component the demo renders — so the fold shows the mechanic working. */
.hero-art{
  display:flex;
  align-items:center;
  justify-content:center;
  /* The capsule is 360px tall. A smaller box made it overflow in both
     directions, which put the top circle over the copy on a phone. */
  min-height:440px;
  padding:40px 0;
}
.hero-capsule{position:relative;width:300px;height:360px;display:flex;align-items:center;justify-content:center}
.hero-cap-top,.hero-cap-bottom{
  position:absolute;left:50%;transform:translateX(-50%);
  width:196px;height:136px;
  border-radius:98px 98px 20px 20px;
}
.hero-cap-top{top:0;background:var(--indigo);box-shadow:inset 0 -1px 0 rgba(15,23,42,.12)}
.hero-cap-top::after{
  content:"";position:absolute;left:26px;top:22px;
  width:46px;height:64px;border-radius:50%;
  background:var(--surface);opacity:.16;
}
.hero-cap-bottom{
  bottom:0;
  border-radius:20px 20px 98px 98px;
  background:var(--surface);
  border:3px solid var(--indigo);
  border-top:0;
}
.hero-cap-bottom::after{
  content:"";position:absolute;left:12px;right:12px;top:6px;height:34px;
  border-radius:0 0 60px 60px;background:var(--indigo-wash);opacity:.85;
}
.hero-seam{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:196px;height:10px;z-index:2;
  background:repeating-linear-gradient(90deg,var(--indigo-soft) 0 7px,transparent 7px 14px);
}
.hero-item{
  position:relative;z-index:4;width:200px;
  background:var(--surface);border:1px solid var(--line-soft);
  border-radius:var(--r-card);padding:12px;
  box-shadow:var(--shadow-card);
}
.hero-item img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:8px;display:block}
.hero-item .hi-name{
  display:block;
  margin-top:10px;font-size:.875rem;font-weight:600;line-height:1.3;
}
/* Tier chip and odds share the second line: the name gets the full width, so
   "Sample Keychain" no longer forces the chip onto its own row. */
.hero-item .hi-meta{
  display:flex;align-items:center;gap:8px;
  margin-top:4px;flex-wrap:wrap;
}
.hero-item .hi-odds{
  font-size:.875rem;color:var(--muted);
  font-variant-numeric:tabular-nums;
}
.hero-item .hi-odds b{color:var(--ink-strong);font-weight:600}
.hero-spark{position:absolute;background:var(--indigo);border-radius:2px;transform:rotate(45deg);opacity:.9}

@media (max-width:900px){
  .hero{grid-template-columns:1fr;gap:8px;min-height:0}
  .hero-copy{padding:40px 0 8px}
  /* 360px capsule + breathing room: the art column must be at least as tall
     as the thing it centres, or the capsule spills over the copy above. */
  .hero-art{min-height:392px;padding:16px 0 32px}
  .hero h1{max-width:24ch}
}

/* --------------------------------------------------------------------------
   Landing — sections and cards
   -------------------------------------------------------------------------- */
.ui-section{padding:64px 0}
.ui-section.tight{padding:48px 0}
.ui-section + .ui-section{border-top:1px solid var(--line-soft)}
.ui-head{margin-bottom:24px}
.ui-head h2{
  font-size:1.75rem;
  line-height:1.3;
  letter-spacing:-.012em;
  margin:0 0 8px;
  color:var(--ink-strong);
}
.ui-head p{margin:0;color:var(--muted);max-width:68ch}

.ui-card{
  background:var(--surface);
  border:1px solid var(--line-soft);
  border-radius:var(--r-card);
  padding:28px;
}
.ui-card.panel{border-radius:var(--r-panel);padding:32px}
.ui-card-head{
  display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  margin-bottom:16px;
}
.ui-card-head h2{font-size:1rem;font-weight:600;margin:0}

/* --------------------------------------------------------------------------
   Buttons
   Scoped to the landing page for now: every other page still renders with the
   style.css button until it is migrated in its own batch.
   -------------------------------------------------------------------------- */
.hero .button,
#demo .button,
.ui-actions .button{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  min-height:48px;
  padding:0 20px;
  border-radius:var(--r-ctl);
  border:1px solid var(--indigo-solid);
  background:var(--indigo-solid);
  color:#fff;
  font-size:1rem;
  font-weight:600;
  text-decoration:none;
  cursor:pointer;
}
.hero .button:hover,
#demo .button:hover,
.ui-actions .button:hover{background:var(--indigo-deep);border-color:var(--indigo-deep)}
.hero .button.secondary,
#demo .button.secondary,
.ui-actions .button.secondary{
  background:var(--surface);
  color:var(--indigo);
  border-color:var(--indigo-soft);
}
.hero .button.secondary:hover,
#demo .button.secondary:hover,
.ui-actions .button.secondary:hover{background:var(--indigo-wash)}
.hero .button.demo-cta{background:var(--indigo-solid);border-color:var(--indigo-solid);color:#fff}

/* The demo template picker: pills, not buttons. */
#demo .demo-buttons{gap:8px;margin:0}
#demo .demo-buttons button{
  min-height:40px;
  padding:0 14px;
  background:var(--surface);
  color:var(--ink-strong);
  border:1px solid var(--line-strong);
  border-radius:999px;
  font-size:.875rem;
  font-weight:600;
}
#demo .demo-buttons button:hover{border-color:var(--ink-strong);background:var(--surface)}
#demo .demo-buttons button[aria-pressed="true"]{
  background:var(--indigo-solid);
  border-color:var(--indigo-solid);
  color:#fff;
}
#demo .demo-buttons button.secondary{
  background:var(--surface);
  color:var(--ink-strong);
  border-color:var(--line-strong);
}

/* --------------------------------------------------------------------------
   Chips, tables, meters
   -------------------------------------------------------------------------- */
/* Tier chips: one neutral pill for every tier. Hue must never read as
   probability — the number stays authoritative. The margin-left is inherited
   from style.css because the chip often sits inline after a name. */
.tier{
  display:inline-flex;
  align-items:center;
  height:22px;
  padding:0 9px;
  border-radius:999px;
  background:var(--indigo-wash);
  color:var(--indigo-deep);
  font-size:.75rem;
  font-weight:600;
  vertical-align:middle;
}
.badge{
  display:inline-flex;
  align-items:center;
  height:22px;
  padding:0 10px;
  border-radius:999px;
  font-size:.75rem;
  font-weight:600;
}
.badge.demo{background:var(--canvas);color:var(--muted);border:1px solid var(--line-soft)}

/* Tables: scoped to the landing page so /admin and /pools keep their own
   table behaviour (sticky first column, zebra) until their batch. */
#transparency .table-wrap{width:100%;overflow-x:auto}
#transparency table{width:100%;border-collapse:collapse;font-size:1rem;background:var(--surface)}
#transparency th{
  font-size:.875rem;
  font-weight:600;
  color:var(--muted);
  text-align:left;
  padding:10px 12px;
  border:0;
  border-bottom:1px solid var(--line-soft);
  white-space:nowrap;
  background:transparent;
}
#transparency td{
  padding:14px 12px;
  border:0;
  border-bottom:1px solid var(--line-soft);
  vertical-align:middle;
  background:transparent;
}
#transparency tbody tr:nth-child(even) td{background:transparent}
#transparency tr:last-child td{border-bottom:0}
#transparency th.num,
#transparency td.num{text-align:right;font-variant-numeric:tabular-nums}
#transparency td.strong{font-weight:600}
#transparency .meter-col{width:22%}
/* Below 760px a five-column table clips a word mid-letter. Each row becomes a
   label/value card instead — the same pattern the app already uses for
   .list-table, so there is one stacking behaviour on the site, not two. */
@media (max-width:760px){
  #transparency thead{display:none}
  #transparency table,
  #transparency tbody,
  #transparency tr,
  #transparency td{display:block;width:100%}
  #transparency tr{
    border:1px solid var(--line-soft);
    border-radius:var(--r-card);
    padding:8px 14px;
    margin-bottom:10px;
  }
  #transparency tr:last-child{margin-bottom:0}
  #transparency td{
    display:grid;
    grid-template-columns:7.5rem 1fr;
    align-items:baseline;
    gap:.4rem;
    padding:5px 0;
    border:0;
    text-align:left;
  }
  #transparency td::before{
    content:attr(data-label);
    font-size:.875rem;
    color:var(--muted);
  }
  /* The spread meter has no useful value at this width; the percentage
     beside it already says the same thing. */
  #transparency td.meter-col{display:none}
}
.ui-meter{
  display:block;height:6px;border-radius:999px;
  background:var(--indigo-wash);overflow:hidden;
}
.ui-meter > span{display:block;height:100%;background:var(--indigo);border-radius:999px}

/* --------------------------------------------------------------------------
   Landing — demo
   -------------------------------------------------------------------------- */
#demo.ui-card{padding:28px}
#demo .demo-stage{
  min-height:220px;
  border:1px dashed var(--line-strong);
  border-radius:var(--r-card);
  background:var(--canvas);
  display:flex;
  align-items:center;
  justify-content:center;
  padding:24px;
  margin-top:20px;
}
/* The sample card in the stage is a preview, not a control: a little wider
   than the hero card so "Sample Charm" and its tier chip stay on one line. */
#demo .demo-stage .hero-item{width:200px}
#demo .demo-foot{
  margin-top:14px;
  color:var(--muted);
  font-size:.875rem;
}

/* --------------------------------------------------------------------------
   Landing — proof columns and plans
   -------------------------------------------------------------------------- */
.ui-cols3{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
.ui-col{
  border:1px solid var(--line-soft);
  border-radius:var(--r-card);
  padding:24px;
  background:var(--surface);
}
.ui-col h3{margin:0 0 8px;font-size:1rem;font-weight:600}
.ui-col p{margin:0;color:var(--muted);font-size:.875rem;line-height:1.6}
@media (max-width:760px){.ui-cols3{grid-template-columns:1fr}}

.ui-plan-list{list-style:none;margin:16px 0 0;padding:0;display:grid;gap:12px;font-size:.875rem}
.ui-plan-list li{display:flex;gap:10px;color:var(--muted);line-height:1.6}
.ui-plan-list li::before{
  content:"";
  flex:0 0 6px;
  width:6px;height:6px;margin-top:7px;
  border-radius:50%;
  background:var(--indigo-soft);
  border:1px solid var(--indigo);
}
.ui-plan-list b{color:var(--ink-strong);font-weight:600}

/* --------------------------------------------------------------------------
   Auth pages (/login, /signup)
   Two clearly separated forms instead of three stacked in one card. The
   password form is the primary path; password reset sits below a divider and
   carries its own field label, because "Email" twice on one page is a defect.
   -------------------------------------------------------------------------- */
.auth{
  max-width:440px;
  margin:40px auto 64px;
}
.auth-card{
  background:var(--surface);
  border:1px solid var(--line-soft);
  border-radius:var(--r-panel);
  padding:32px;
}
.auth-card + .auth-card{margin-top:16px}
.auth h1{
  font-size:2rem;
  line-height:1.22;
  letter-spacing:-.015em;
  margin:0 0 8px;
}
.auth .auth-lede{color:var(--muted);margin:0 0 28px;font-size:1rem}
.auth h2{
  font-size:1rem;
  font-weight:600;
  margin:0 0 18px;
}

.field{display:grid;gap:6px;margin-bottom:18px}
.field > label{font-size:.875rem;font-weight:600;color:var(--ink-strong)}
.field input{
  min-height:48px;
  height:48px;
  width:100%;
  padding:0 14px;
  border:1px solid var(--line-strong);
  border-radius:var(--r-ctl);
  font:inherit;
  font-size:1rem;
  background:var(--surface);
  color:var(--ink-strong);
}
.field input:focus{
  outline:none;
  border-color:var(--indigo);
  box-shadow:0 0 0 3px rgba(67,56,202,.14);
}
.field input[aria-invalid="true"]{border-color:var(--danger-ink)}
.field .helper{font-size:.875rem;color:var(--muted);margin:0}
/* Error text never relies on red alone: it carries a worded prefix. */
.field .field-error{
  font-size:.875rem;
  font-weight:600;
  color:var(--danger-ink);
  margin:0;
}

.auth .button,
.auth button:not(.link){
  width:100%;
  min-height:48px;
  padding:0 20px;
  border-radius:var(--r-ctl);
  border:1px solid var(--indigo-solid);
  background:var(--indigo-solid);
  color:#fff;
  font-size:1rem;
  font-weight:600;
}
.auth .button:hover,
.auth button:not(.link):hover{background:var(--indigo-deep);border-color:var(--indigo-deep)}
.auth .button.secondary,
.auth button.secondary{
  background:var(--surface);
  color:var(--ink-strong);
  border-color:var(--line-strong);
}
.auth button.secondary:hover{background:var(--canvas);border-color:var(--muted)}
.auth button[disabled],
.auth .button[aria-disabled="true"]{
  background:var(--canvas);
  color:var(--muted);
  border-color:var(--line-soft);
  cursor:not-allowed;
}

.auth-divider{
  display:flex;
  align-items:center;
  gap:12px;
  margin:26px 0;
  color:var(--muted);
  font-size:.875rem;
}
.auth-divider::before,
.auth-divider::after{
  content:"";
  flex:1;
  height:1px;
  background:var(--line-soft);
}
.auth-note{font-size:.875rem;color:var(--muted);margin:16px 0 0}
.auth-note a{color:var(--indigo);text-decoration:none;font-weight:600}
.auth-legal{font-size:.875rem;color:var(--muted);margin:24px 0 0;text-align:center}
.auth-legal a{color:var(--muted)}

/* The dev sign-in block is a development affordance, not part of the product
   surface: it reads as a footnote so it cannot be mistaken for a real path. */
.auth-dev{
  margin-top:24px;
  border:1px dashed var(--line-strong);
  border-radius:var(--r-card);
  padding:20px;
  background:var(--canvas);
}
.auth-dev h2{font-size:.875rem;color:var(--muted);margin:0 0 14px}
/* The reset form is folded: it is a rare path, and an open second "Email"
   field made a one-job page look like it had two. */
.auth-reset{padding:0}
.auth-reset > summary{
  cursor:pointer;list-style:none;padding:20px 32px;
  font-size:.875rem;font-weight:600;color:var(--muted);
  min-height:44px;display:flex;align-items:center;
}
.auth-reset > summary::-webkit-details-marker{display:none}
.auth-reset > summary::before{content:"+ ";font-weight:700}
.auth-reset[open] > summary::before{content:"\2212 "}
.auth-reset[open] > summary{color:var(--ink-strong);padding-bottom:0}
.auth-reset form{padding:0 32px 32px}

/* --------------------------------------------------------------------------
   Help page (/help)
   Eleven sections is long by nature, so the page carries its own navigation
   and caps prose at 68ch. The FAQ is ten disclosures instead of one blob.
   -------------------------------------------------------------------------- */
.doc-page{padding:48px 0 24px}
.doc-head{max-width:68ch;margin-bottom:32px}
.doc-head h1{margin:0 0 16px}
.doc-head .prose{font-size:1rem;line-height:1.65;color:var(--muted)}
.doc-head .prose strong{color:var(--ink-strong)}

.doc-body{
  display:grid;
  grid-template-columns:minmax(0,1fr) 240px;
  gap:56px;
  align-items:start;
}
.doc-sections{display:grid;gap:16px;min-width:0}
.doc-sections .ui-card{padding:28px 32px}
.doc-sections .ui-card h2{
  font-size:1.75rem;
  line-height:1.3;
  letter-spacing:-.012em;
  margin:0 0 16px;
}
.doc-sections .prose{max-width:68ch;font-size:1rem;line-height:1.65}
.doc-sections .prose ul,
.doc-sections .prose ol{margin:0 0 14px;padding-left:22px}
.doc-sections .prose li{margin:6px 0}
.doc-sections .prose p{margin:0 0 14px}
.doc-sections .prose p:last-child{margin-bottom:0}
/* A long URL is one unbreakable token: at 358px of card width it pushed the
   page 28px sideways on a phone. The catalog keeps that URL as plain text
   (not a markdown link), so the wrap has to sit on the prose container, not
   on anchors only. */
.doc-sections .prose,
.doc-head .prose{overflow-wrap:anywhere}

/* Sticky rail: the page is ~4000px tall, so the contents have to travel. */
.doc-rail{
  position:sticky;
  top:88px;
  font-size:.875rem;
  align-self:start;
}
.doc-rail-head{
  font-weight:600;
  color:var(--ink-strong);
  margin:0 0 10px;
}
.doc-rail ol{list-style:none;margin:0;padding:0;display:grid;gap:2px}
.doc-rail a{
  display:block;
  padding:6px 0 6px 12px;
  color:var(--muted);
  text-decoration:none;
  border-left:2px solid var(--line-soft);
  line-height:1.4;
}
.doc-rail a:hover{color:var(--indigo);border-left-color:var(--indigo-soft)}

.doc-toc-mobile{
  display:none;
  margin-bottom:24px;
  border:1px solid var(--line-soft);
  border-radius:var(--r-card);
  padding:14px 16px;
  background:var(--surface);
}
.doc-toc-mobile summary{
  font-weight:600;
  font-size:.875rem;
  cursor:pointer;
  color:var(--ink-strong);
}
.doc-toc-mobile ol{
  margin:12px 0 0;
  padding-left:18px;
  font-size:.875rem;
  color:var(--muted);
}
.doc-toc-mobile li{margin:6px 0}
.doc-toc-mobile a{color:var(--muted);text-decoration:none}

/* Tier scale as one row of chips: C -> LR is a single vocabulary, not seven
   bullets that repeat the same shape. */
.tier-row{
  display:flex;
  flex-wrap:wrap;
  gap:8px;
  margin:0 0 20px;
}
.tier-chip{
  display:inline-flex;
  align-items:center;
  gap:6px;
  height:28px;
  padding:0 12px;
  border-radius:999px;
  background:var(--indigo-wash);
  color:var(--indigo-deep);
  font-size:.875rem;
  font-weight:600;
}
.tier-chip b{font-weight:700}

/* FAQ: one disclosure per question. */
.faq{display:grid;gap:0;border-top:1px solid var(--line-soft)}
.faq-item{border-bottom:1px solid var(--line-soft)}
.faq-item summary{
  list-style:none;
  display:flex;
  align-items:center;
  gap:12px;
  cursor:pointer;
  padding:16px 0;
  font-size:1rem;
  font-weight:600;
  color:var(--ink-strong);
}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::after{
  content:"+";
  margin-left:auto;
  color:var(--muted);
  font-weight:400;
  font-size:20px;
  line-height:1;
}
.faq-item[open] summary::after{content:"−"}
.faq-item[open] summary{padding-bottom:8px}
.faq-item .prose{padding:0 0 18px;max-width:68ch}

@media (max-width:1000px){
  .doc-body{grid-template-columns:minmax(0,1fr);gap:0}
  .doc-rail{display:none}
  .doc-toc-mobile{display:block}
}
@media (max-width:760px){
  .doc-page{padding:32px 0 16px}
  .doc-sections .ui-card{padding:24px 20px}
  .doc-sections .ui-card h2{font-size:1.5rem}
}

/* --------------------------------------------------------------------------
   Data table — the shared component for /rates, /leaderboard and the app.
   Header on a hairline, row separators, numbers right-aligned tabular. Zebra
   is off: the separator already does the work, and a stripe fights the meter.
   -------------------------------------------------------------------------- */
.ui-table-wrap{width:100%;overflow-x:auto}
.ui-table{width:100%;border-collapse:collapse;font-size:1rem;background:var(--surface)}
.ui-table th{
  font-size:.875rem;font-weight:600;color:var(--muted);text-align:left;
  padding:10px 12px;border:0;border-bottom:1px solid var(--line-soft);
  white-space:nowrap;background:transparent;
}
.ui-table td{
  padding:14px 12px;border:0;border-bottom:1px solid var(--line-soft);
  vertical-align:middle;background:transparent;
}
.ui-table tbody tr:nth-child(even) td{background:transparent}
.ui-table tr:last-child td{border-bottom:0}
.ui-table th.num,.ui-table td.num{text-align:right;font-variant-numeric:tabular-nums}
.ui-table td.strong{font-weight:600}
.ui-table .meter-col{width:20%}

@media (max-width:760px){
  /* Five columns cannot fit 390px without clipping a word mid-letter. Each
     row becomes a label/value card, the same pattern the app already uses. */
  .ui-table thead{display:none}
  .ui-table,.ui-table tbody,.ui-table tr,.ui-table td{display:block;width:100%}
  .ui-table tr{
    border:1px solid var(--line-soft);border-radius:var(--r-card);
    padding:10px 14px;margin-bottom:10px;
  }
  .ui-table tr:last-child{margin-bottom:0}
  .ui-table td{
    display:grid;grid-template-columns:7.5rem 1fr;align-items:baseline;
    gap:.4rem;padding:5px 0;border:0;text-align:left;
  }
  .ui-table td::before{content:attr(data-label);font-size:.875rem;color:var(--muted)}
  .ui-table td.meter-col{display:none}
  /* Only the combined-odds table uses an empty label, for its route-total
     filler cell. Scoping it there keeps real cells with data-label="" (the
     actions column on /pools) visible — hiding every empty label deleted the
     whole action cluster on a phone. */
  .combined-table td[data-label=""]{display:none}
}

/* --------------------------------------------------------------------------
   Summary facts strip + empty state
   -------------------------------------------------------------------------- */
.ui-facts{
  display:flex;flex-wrap:wrap;gap:12px 40px;margin:0;padding:0;
}
.ui-facts > div{display:grid;gap:2px}
.ui-facts dt{font-size:.875rem;color:var(--muted)}
.ui-facts dd{
  margin:0;font-size:1rem;font-weight:600;color:var(--ink-strong);
  font-variant-numeric:tabular-nums;
}
.ui-empty{
  margin:0;padding:40px 24px;text-align:center;
  color:var(--muted);font-size:.875rem;
}

/* --------------------------------------------------------------------------
   Leaderboard
   Three windows side by side; rank is a number, never a colour cue alone.
   -------------------------------------------------------------------------- */
.ui-lb-tabs{display:flex;gap:8px;margin:0 0 28px}
.ui-lb-tabs a{
  display:inline-flex;align-items:center;min-height:40px;padding:0 16px;
  border-radius:var(--r-ctl);border:1px solid var(--line-strong);
  background:var(--surface);color:var(--ink-strong);font-size:.875rem;font-weight:600;
  text-decoration:none;
}
.ui-lb-tabs a.is-active{background:var(--indigo-solid);border-color:var(--indigo-solid);color:#fff}

.ui-lb-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;align-items:start}
.ui-lb-col{background:var(--surface);border:1px solid var(--line-soft);border-radius:var(--r-card);padding:20px 24px}
.ui-lb-col h2{font-size:1rem;font-weight:600;margin:0 0 12px}
.ui-lb-list{list-style:none;margin:0;padding:0;display:grid;gap:0}
.ui-lb-row{
  display:flex;align-items:center;gap:12px;
  padding:10px 0;border-bottom:1px solid var(--line-soft);
}
.ui-lb-row:last-child{border-bottom:0}
.ui-lb-rank{
  flex:0 0 22px;text-align:center;
  font-size:.875rem;font-weight:600;color:var(--muted);
  font-variant-numeric:tabular-nums;
}
/* The top three carry a filled rank badge, so rank is legible without colour
   vision — the number itself is the cue, the badge only groups them. */
.ui-lb-row.is-top .ui-lb-rank{
  background:var(--indigo-wash);color:var(--indigo-deep);
  border-radius:999px;height:22px;line-height:22px;
}
.ui-lb-avatar{
  width:28px;height:28px;border-radius:999px;object-fit:cover;
  border:1px solid var(--line-soft);flex:0 0 auto;
}
.ui-lb-name{
  flex:1;min-width:0;font-weight:600;font-size:.875rem;
  color:var(--ink-strong);text-decoration:none;
  overflow-wrap:anywhere;
}
.ui-lb-name:hover{color:var(--indigo)}
.ui-lb-count{
  color:var(--muted);font-size:.875rem;white-space:nowrap;
  font-variant-numeric:tabular-nums;
}

@media (max-width:900px){.ui-lb-grid{grid-template-columns:1fr}}

/* --------------------------------------------------------------------------
   Public pool page (/p/<id>)
   Sticky summary panel beside the item rows. On a phone the panel comes
   first: the price and the stock are what a buyer needs before scrolling.
   -------------------------------------------------------------------------- */
.pool-split{
  display:grid;grid-template-columns:minmax(0,1fr) 320px;
  gap:32px;align-items:start;margin-top:32px;
}
.pool-panel{
  position:sticky;top:88px;
  background:var(--surface);border:1px solid var(--line-soft);
  border-radius:var(--r-panel);padding:24px;
}
.pool-panel .ui-facts{display:grid;gap:10px;margin:0 0 20px}
.pool-panel .ui-facts > div{
  display:flex;justify-content:space-between;gap:12px;
  padding:8px 0;border-bottom:1px solid var(--line-soft);
}
.pool-panel .ui-facts > div:last-child{border-bottom:0}
.pool-panel .ui-facts dt{font-size:.875rem;color:var(--muted)}
.pool-panel .ui-facts dd{margin:0;font-weight:600;font-size:.875rem}
.pool-panel .pool-price{
  font-size:1.75rem;font-weight:700;line-height:1.2;
  letter-spacing:-.012em;margin:0 0 4px;
  font-variant-numeric:tabular-nums;
}
.pool-panel .pool-price-note{font-size:.875rem;color:var(--muted);margin:0}
.pool-panel .pool-hint{
  font-size:.875rem;color:var(--muted);line-height:1.6;
  margin:20px 0 0;padding-top:16px;border-top:1px solid var(--line-soft);
}

/* Item rows: art, name, neutral tier chip, odds. The number is authoritative,
   so it sits right-aligned in tabular figures. */
.pool-items{
  border:1px solid var(--line-soft);border-radius:var(--r-card);
  background:var(--surface);overflow:hidden;
}
/* Scoped to the public pool page: .item-card is also the editor's item card,
   and an unscoped rule here restyled every editor row (padding, border-bottom,
   flex) the moment ui.css loaded after style.css. */
.pool-items .item-card{
  display:flex;align-items:center;gap:16px;
  padding:14px 20px;border-bottom:1px solid var(--line-soft);
  background:var(--surface);margin:0;border-radius:0;
}
.pool-items .item-card:last-child{border-bottom:0}
.pool-items .item-card .item-thumb{
  flex:0 0 56px;width:56px;height:44px;border-radius:8px;
  background:var(--canvas);border:1px solid var(--line-soft);
  overflow:hidden;display:flex;align-items:center;justify-content:center;
}
.pool-items .item-card .item-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.pool-items .item-card .item-thumb span{font-size:.75rem;color:var(--muted);text-align:center;padding:0 4px}
.pool-items .item-card .item-info{flex:1;min-width:0}
.pool-items .item-card .name{
  font-weight:600;font-size:1rem;color:var(--ink-strong);
  overflow-wrap:anywhere;
}
.pool-items .item-card .item-meta{
  display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;
  margin-top:4px;font-size:.875rem;color:var(--muted);
}
.pool-items .item-card .item-odds{
  flex:0 0 auto;text-align:right;
  font-variant-numeric:tabular-nums;
}
.pool-items .item-card .item-odds b{
  display:block;font-size:1rem;font-weight:600;color:var(--ink-strong);
}
.pool-items .item-card .item-odds small{font-size:.75rem;color:var(--muted)}

@media (max-width:900px){
  .pool-split{grid-template-columns:1fr;gap:20px;margin-top:24px}
  .pool-panel{position:static;order:-1}
}
@media (max-width:760px){
  .pool-items .item-card{padding:12px 14px;gap:12px}
  .pool-items .item-card .item-thumb{flex:0 0 48px;width:48px;height:38px}
}

/* --------------------------------------------------------------------------
   Receipt (/r/<code>)
   A ticket, not a marketing page: perforated seams, the code as the largest
   element, then only recorded facts. Monospace is reserved for values a
   person might copy or recompute.
   -------------------------------------------------------------------------- */
.receipt-wrap{max-width:600px;margin:0 auto}
.receipt{
  background:var(--surface);border:1px solid var(--line-soft);
  border-radius:var(--r-panel);overflow:hidden;
}
.receipt-top{padding:32px 32px 26px}
.receipt-kicker{
  font-size:.875rem;font-weight:600;color:var(--muted);
  text-transform:uppercase;letter-spacing:.06em;margin:0 0 8px;
}
/* The code is the one thing a person needs to keep: it gets the largest
   type on the page and wraps mid-token rather than overflowing. */
.receipt-code{
  font-size:1.75rem;font-weight:700;line-height:1.2;
  letter-spacing:.01em;margin:0;color:var(--ink-strong);
  font-variant-numeric:tabular-nums;overflow-wrap:anywhere;
}
.receipt-time{font-size:.875rem;color:var(--muted);margin:10px 0 0}

/* Perforated seam: a dotted line with a punched notch at each edge, so the
   page reads as a torn ticket rather than a card with a border. */
.receipt-seam{
  position:relative;height:0;
  border-top:1px dashed var(--line-strong);
  margin:0 16px;
}
.receipt-seam::before,
.receipt-seam::after{
  content:"";position:absolute;top:-9px;
  width:18px;height:18px;border-radius:50%;
  background:var(--canvas);border:1px solid var(--line-soft);
}
.receipt-seam::before{left:-25px}
.receipt-seam::after{right:-25px}

.receipt-body{padding:26px 32px 8px}
.receipt-item{margin-bottom:22px}
.receipt-item-name{
  display:flex;align-items:center;flex-wrap:wrap;gap:8px;
  font-size:1.75rem;font-weight:700;line-height:1.25;
  letter-spacing:-.012em;color:var(--ink-strong);
  overflow-wrap:anywhere;
}
.receipt-item-odds{
  margin:6px 0 0;font-size:1rem;font-weight:600;
  color:var(--ink-strong);font-variant-numeric:tabular-nums;
}
.receipt-item-odds span{font-weight:400;color:var(--muted);font-size:.875rem}

.receipt-row-label{
  font-size:.875rem;font-weight:600;color:var(--muted);
  margin:0 0 10px;
}
.receipt-rows{margin:0;padding:0}
.receipt-rows > div{
  display:flex;justify-content:space-between;gap:20px;
  padding:11px 0;border-bottom:1px solid var(--line-soft);
}
.receipt-rows > div:last-child{border-bottom:0}
.receipt-rows dt{font-size:.875rem;color:var(--muted);flex:0 0 auto}
.receipt-rows dd{
  margin:0;font-size:.875rem;font-weight:600;color:var(--ink-strong);
  text-align:right;font-variant-numeric:tabular-nums;min-width:0;
}
.receipt-rows dd.mono{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:.8125rem;font-weight:400;
}
.receipt-rows dd.break{overflow-wrap:anywhere;word-break:break-word}

.receipt-chain{margin:0 0 22px}
.receipt-chain .chain-walk{
  display:flex;flex-wrap:wrap;align-items:center;gap:6px;
  font-size:.875rem;
}
.receipt-chain .chain-step{
  display:inline-flex;align-items:center;gap:6px;
  padding:6px 10px;border:1px solid var(--line-soft);
  border-radius:var(--r-ctl);background:var(--canvas);
}
.receipt-chain .chain-leaf{border-color:var(--indigo-soft);background:var(--indigo-wash)}
.receipt-chain .chain-stage{font-size:.75rem;color:var(--muted);font-weight:600}
.receipt-chain .chain-arrow{color:var(--line-strong)}

.receipt-fair{
  margin-top:8px;padding:18px 0 0;
  border-top:1px solid var(--line-soft);
}
.receipt-verify{
  font-size:.875rem;color:var(--muted);line-height:1.6;
  margin:14px 0 0;
}

.receipt-foot{
  display:flex;flex-wrap:wrap;align-items:center;gap:20px;
  padding:24px 32px 32px;
}
.receipt-qr{flex:0 0 auto}
.receipt-qr img{width:88px;height:88px;display:block;border-radius:8px}
.receipt-actions{flex:1;min-width:180px;margin:0}
.receipt-actions button{
  width:100%;min-height:44px;padding:0 18px;
  background:var(--surface);color:var(--ink-strong);
  border:1px solid var(--line-strong);border-radius:var(--r-ctl);
  font-size:.875rem;font-weight:600;
}
.receipt-actions button:hover{border-color:var(--ink-strong)}

@media (max-width:760px){
  .receipt-top,.receipt-body,.receipt-foot{padding-left:20px;padding-right:20px}
  .receipt-seam{margin:0 10px}
  .receipt-seam::before{left:-19px}
  .receipt-seam::after{right:-19px}
  .receipt-code{font-size:1.25rem}
  .receipt-item-name{font-size:1.375rem}
  .receipt-rows > div{flex-direction:column;gap:2px}
  .receipt-rows dd{text-align:left}
}

/* --------------------------------------------------------------------------
   Public seller page (/s/<id>)
   Header with avatar, then a grid of published pools. The trust line is
   counted from published pools and recorded draws, never typed by the seller.
   -------------------------------------------------------------------------- */
.seller-head{
  display:flex;align-items:flex-start;gap:20px;
  padding-bottom:28px;border-bottom:1px solid var(--line-soft);
}
.seller-head .seller-avatar{
  width:56px;height:56px;border-radius:999px;object-fit:cover;
  border:1px solid var(--line-soft);flex:0 0 auto;margin:4px 0 0;
}
.seller-id{min-width:0;flex:1}
.seller-id h1{
  display:flex;align-items:center;flex-wrap:wrap;gap:10px;
  font-size:2rem;line-height:1.22;letter-spacing:-.015em;
  margin:0 0 6px;overflow-wrap:anywhere;
}
.seller-trust{font-size:.875rem;color:var(--muted);margin:0 0 10px}
.seller-trust a{color:var(--muted)}
.seller-bio{
  max-width:68ch;font-size:1rem;line-height:1.65;
  color:var(--ink-strong);margin:0;overflow-wrap:anywhere;
}

.seller-pools{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.seller-pool{
  display:flex;flex-direction:column;
  background:var(--surface);border:1px solid var(--line-soft);
  border-radius:var(--r-card);padding:22px;
}
.seller-pool h3{
  font-size:1rem;font-weight:600;line-height:1.4;
  margin:0 0 8px;overflow-wrap:anywhere;
}
.seller-pool h3 a{color:var(--ink-strong);text-decoration:none}
.seller-pool h3 a:hover{color:var(--indigo)}
.seller-pool-meta{font-size:.875rem;color:var(--muted);margin:0 0 10px;line-height:1.5}
.seller-pool-odds{
  font-size:.875rem;color:var(--muted);margin:0 0 18px;
  font-variant-numeric:tabular-nums;
}
.seller-pool-odds b{color:var(--ink-strong);font-weight:600}
.seller-pool-action{margin:auto 0 0}
.seller-pool-action .button{width:100%}

@media (max-width:900px){.seller-pools{grid-template-columns:repeat(2,1fr)}}
@media (max-width:600px){
  .seller-pools{grid-template-columns:1fr}
  .seller-head{gap:14px}
  .seller-id h1{font-size:1.5rem}
}

/* --------------------------------------------------------------------------
   Changelog + contact
   -------------------------------------------------------------------------- */
.log-list{display:grid;gap:0;margin-top:32px}
.log-entry{
  display:grid;grid-template-columns:180px minmax(0,1fr);gap:32px;
  padding:28px 0;border-top:1px solid var(--line-soft);
}
.log-entry:last-child{border-bottom:1px solid var(--line-soft)}
.log-rail{display:flex;flex-direction:column;gap:8px;align-items:flex-start}
.log-version{
  font-size:.875rem;color:var(--muted);
  font-variant-numeric:tabular-nums;
}
.log-body{min-width:0}
.log-body h2{
  font-size:1.75rem;line-height:1.3;letter-spacing:-.012em;
  margin:0 0 12px;
}
.log-body .prose{max-width:68ch;font-size:1rem;line-height:1.65}

.contact-cards{display:grid;grid-template-columns:repeat(2,1fr);gap:24px;max-width:720px}
.contact-cards .ui-card{padding:24px}
.contact-cards .prose{max-width:68ch;font-size:.875rem;line-height:1.65}

@media (max-width:760px){
  .log-entry{grid-template-columns:1fr;gap:12px;padding:24px 0}
  .log-body h2{font-size:1.375rem}
  .contact-cards{grid-template-columns:1fr}
}
/* The contact page keeps a plain <h1> (no wrapper or inline style) so the
   heading stays one predictable node; the size comes from here. */
.contact-head h1{
  font-size:2rem;line-height:1.22;letter-spacing:-.015em;margin:0 0 10px;
}

/* --------------------------------------------------------------------------
   Sample gallery
   The artwork is untouched — this only evens the tiles so a row lines up.
   -------------------------------------------------------------------------- */
.sample-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));
  gap:16px;margin:0;
}
.sample-card{
  margin:0;display:flex;flex-direction:column;gap:12px;
  border:1px solid var(--line-soft);border-radius:var(--r-card);
  background:var(--surface);padding:12px;height:100%;
}
.sample-card img{
  width:100%;aspect-ratio:4/3;object-fit:cover;
  border-radius:8px;display:block;background:var(--canvas);
}
.sample-card figcaption{
  display:flex;align-items:center;justify-content:space-between;
  gap:8px;flex-wrap:wrap;margin-top:auto;
}
.sample-card .name{font-weight:600;font-size:.875rem;overflow-wrap:anywhere}
.sample-card .button{
  min-height:36px;padding:0 12px;font-size:.875rem;
  background:var(--surface);color:var(--ink-strong);border:1px solid var(--line-strong);
}
.sample-card .button:hover{background:var(--canvas);border-color:var(--muted)}

/* --------------------------------------------------------------------------
   Calculator (/calculator)
   Inputs left, sticky result right. The margin per pull is the number the
   page exists for, so it gets the metric size rather than the bottom of a
   long table.
   -------------------------------------------------------------------------- */
.calc-split{
  display:grid;grid-template-columns:minmax(0,1fr) 340px;
  gap:32px;align-items:start;margin-top:32px;
}
.calc-inputs{min-width:0}
.calc-result{position:sticky;top:88px}
.calc-result-card h2{
  font-size:.875rem;font-weight:600;color:var(--muted);
  text-transform:uppercase;letter-spacing:.05em;margin:0 0 10px;
}
.calc-metric{
  font-size:1.75rem;font-weight:700;line-height:1.2;
  letter-spacing:-.012em;margin:0;
  font-variant-numeric:tabular-nums;color:var(--ink-strong);
  overflow-wrap:anywhere;
}
.calc-metric.negative{color:var(--danger-ink)}
.calc-metric-note{font-size:.875rem;color:var(--muted);margin:4px 0 20px}
.calc-facts{display:grid;gap:0;margin:0}
.calc-facts > div{
  display:flex;justify-content:space-between;gap:12px;
  padding:10px 0;border-bottom:1px solid var(--line-soft);
}
.calc-facts > div:last-child{border-bottom:0}
.calc-facts dt{font-size:.875rem;color:var(--muted)}
.calc-facts dd{
  margin:0;font-size:.875rem;font-weight:600;text-align:right;
  font-variant-numeric:tabular-nums;
}
.calc-facts dd.negative{color:var(--danger-ink)}
.calc-projection{margin-top:20px;padding-top:18px;border-top:1px solid var(--line-soft)}
.calc-projection h3{font-size:.875rem;font-weight:600;margin:0 0 10px;color:var(--ink-strong)}
.calc-result-empty .ui-empty{padding:32px 0}

.calc-warnings{margin-top:16px;display:grid;gap:8px}
.calc-warning{
  margin:0;padding:12px 14px;border-radius:var(--r-ctl);
  background:#fef3c7;color:#78350f;font-size:.875rem;line-height:1.5;
}

/* Manual-entry rows: cost + weight + remove, on one line. */
.calc-row{display:flex;gap:8px;align-items:center;margin:0 0 8px}
.calc-row input{flex:1;min-width:0;height:44px;min-height:44px}
.calc-row .calc-row-remove{
  flex:0 0 44px;width:44px;min-height:44px;padding:0;
  background:var(--surface);color:var(--muted);border:1px solid var(--line-strong);
  border-radius:var(--r-ctl);font-size:1.25rem;line-height:1;
}
.calc-row .calc-row-remove:hover{border-color:var(--danger-ink);color:var(--danger-ink)}

/* Cost inputs inside the table are the one editable cell in a data table. */
.calc-costs input{
  width:110px;height:40px;min-height:40px;text-align:right;
  font-variant-numeric:tabular-nums;padding:0 10px;
}

.recap-filter{display:flex;flex-wrap:wrap;gap:16px;align-items:flex-end;margin:0 0 20px}
.recap-filter .field{margin:0;flex:1 1 150px}

.negative{color:var(--danger-ink)}

@media (max-width:900px){
  .calc-split{grid-template-columns:1fr;gap:20px;margin-top:24px}
  /* On a phone the result comes first: the answer is why the page was opened. */
  .calc-result{position:static;order:-1}
}

/* --------------------------------------------------------------------------
   Report form (/report)
   One column, 560px. The target is stated before the fields so a report
   cannot be filed against the wrong thing.
   -------------------------------------------------------------------------- */
.report-wrap{max-width:560px;margin:0 auto}
.report-target{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  margin:0 0 24px;padding:14px 16px;
  background:var(--canvas);border:1px solid var(--line-soft);
  border-radius:var(--r-ctl);
}
.report-target-label{font-size:.875rem;color:var(--muted)}
.report-target-name{
  font-size:1rem;font-weight:600;color:var(--ink-strong);
  overflow-wrap:anywhere;
}
.report-wrap .field textarea{
  width:100%;padding:12px 14px;border:1px solid var(--line-strong);
  border-radius:var(--r-ctl);font:inherit;font-size:1rem;
  background:var(--surface);color:var(--ink-strong);resize:vertical;
}
.report-wrap .field textarea:focus{
  outline:none;border-color:var(--indigo);
  box-shadow:0 0 0 3px rgba(67,56,202,.14);
}
.report-wrap .field select{
  min-height:48px;height:48px;width:100%;padding:0 12px;
  border:1px solid var(--line-strong);border-radius:var(--r-ctl);
  font:inherit;font-size:1rem;background:var(--surface);color:var(--ink-strong);
}
.report-wrap button[type="submit"]{
  width:100%;min-height:48px;border-radius:var(--r-ctl);
  background:var(--indigo-solid);border:1px solid var(--indigo-solid);
  color:#fff;font-size:1rem;font-weight:600;
}
.report-wrap button[type="submit"]:hover{background:var(--indigo-deep)}

/* --------------------------------------------------------------------------
   Game table (/g/<code>)
   Order follows what a player needs on arrival: whose turn (and the button),
   then the seats, then the rolls. The code is a value to share, so it is set
   in tabular figures beside a copy button.
   -------------------------------------------------------------------------- */
.session-page{max-width:1120px}
.session-head{margin-bottom:28px}
.session-head h1{
  font-size:2rem;line-height:1.22;letter-spacing:-.015em;
  margin:0 0 14px;overflow-wrap:anywhere;
}
.session-code-row{
  display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin:0 0 8px;
}
.session-code-label{font-size:.875rem;color:var(--muted)}
.session-code{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:1.25rem;font-weight:700;letter-spacing:.08em;
  color:var(--ink-strong);
}
.session-copy{
  min-height:40px;padding:0 14px;
  background:var(--surface);color:var(--ink-strong);
  border:1px solid var(--line-strong);border-radius:var(--r-ctl);
  font-size:.875rem;font-weight:600;
}
.session-copy:hover{border-color:var(--ink-strong)}
.session-hint{font-size:.875rem;color:var(--muted);margin:0}

.session-turn{margin-bottom:32px;border-radius:var(--r-panel)}
.session-turn-line{
  font-size:1.75rem;font-weight:700;line-height:1.25;
  letter-spacing:-.012em;margin:0 0 6px;color:var(--ink-strong);
}
.session-turn-hint{font-size:.875rem;color:var(--muted);margin:0 0 20px}
.session-stale{font-size:.875rem;color:var(--danger-ink);margin:0 0 16px}
.session-turn button[type="submit"]{
  min-width:180px;min-height:48px;border-radius:var(--r-ctl);
  background:var(--indigo-solid);border:1px solid var(--indigo-solid);
  color:#fff;font-size:1rem;font-weight:600;
}
.session-turn button[type="submit"]:hover{background:var(--indigo-deep)}
.session-turn button[type="submit"][disabled]{
  background:var(--canvas);color:var(--muted);border-color:var(--line-soft);
  cursor:not-allowed;
}

.session-closed{margin-bottom:24px}
.session-closed p{margin:0;color:var(--muted);font-size:.875rem}

.session-split{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:32px;align-items:start;
}
.session-split .ui-table td.current-turn,
.session-split tr.current-turn td{background:var(--indigo-wash)}
.session-split .ui-table tr.current-turn td:first-child{font-weight:700}
.session-time{color:var(--muted);white-space:nowrap;font-size:.875rem}
.session-all{margin:14px 0 0;font-size:.875rem}
.session-all a{color:var(--indigo);text-decoration:none;font-weight:600}

.session-owner{
  margin-top:32px;padding-top:24px;border-top:1px solid var(--line-soft);
  display:flex;flex-wrap:wrap;gap:16px;align-items:center;justify-content:space-between;
}
.session-cost{margin:0;font-size:.875rem;color:var(--muted);max-width:56ch}
.session-owner button.danger{
  min-height:44px;padding:0 18px;border-radius:var(--r-ctl);
  background:var(--surface);color:var(--danger-ink);
  border:1px solid var(--danger-ink);font-size:.875rem;font-weight:600;
}
.session-owner button.danger:hover{background:#fef2f2}

@media (max-width:900px){
  .session-split{grid-template-columns:1fr;gap:28px}
}
@media (max-width:760px){
  .session-head h1{font-size:1.5rem}
  .session-turn-line{font-size:1.375rem}
  .session-turn button[type="submit"]{width:100%}
}

/* --------------------------------------------------------------------------
   Dashboard (/dashboard)
   Two bands (player, then publisher), one action row, then two short feeds.
   Every list stays at five rows with a link to the page that lists all of it.
   -------------------------------------------------------------------------- */
.dash-head h1{
  font-size:2rem;line-height:1.22;letter-spacing:-.015em;margin:0 0 8px;
}
.dash-head p{margin:0;color:var(--muted)}
.dash-card{margin-top:20px}
.dash-card-title{
  font-size:1rem;font-weight:600;margin:0 0 16px;color:var(--ink-strong);
}
.dash-card .stat-grid{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;
}
.dash-card .stat{
  background:var(--canvas);border:1px solid var(--line-soft);
  border-radius:var(--r-card);padding:16px 18px;
  display:flex;flex-direction:column;gap:2px;
}
.dash-card .stat-num{
  font-size:1.75rem;font-weight:700;line-height:1.15;
  font-variant-numeric:tabular-nums;color:var(--ink-strong);
}
.dash-card .stat-label{color:var(--muted);font-size:.875rem}

.dash-actions{
  display:flex;flex-wrap:wrap;gap:10px;align-items:center;
  margin:24px 0 0;
}
.dash-actions .button,
.dash-actions button{
  min-height:44px;padding:0 16px;font-size:.875rem;
}

.dash-feeds{display:grid;gap:24px;margin-top:24px;align-items:start}
/* One column, not two. Side by side looked tidy but squeezed a four-column
   table into 516px, where "Gacha stok terbatas (200)" wrapped onto three
   lines — a table has to be readable before the grid is neat. align-items
   start keeps an empty feed from stretching to its neighbour's height. */
.dash-feed{padding:0}
.dash-feed .ui-card-head{padding:20px 24px 0;margin-bottom:8px}
.dash-feed .ui-card-head h2{font-size:1rem;font-weight:600;margin:0}
.dash-feed .ui-table td,
.dash-feed .ui-table th{padding-left:24px;padding-right:24px}
.dash-feed .ui-empty{padding:32px 24px}
.dash-time{color:var(--muted);white-space:nowrap;font-size:.875rem}
.dash-intro{margin:28px 0 0;font-size:.875rem;color:var(--muted)}

/* Monthly pull allowance: the remaining number is the figure that decides
   whether the next pull costs anything, so it gets the metric size. */
.dash-quota .quota-head{
  display:flex;align-items:baseline;justify-content:space-between;
  gap:12px;flex-wrap:wrap;margin-bottom:6px;
}
.dash-quota .dash-card-title{margin:0}
.quota-plan{
  font-size:.75rem;font-weight:600;color:var(--indigo-deep);
  background:var(--indigo-wash);border-radius:999px;padding:3px 10px;
}
.quota-figure{display:flex;align-items:baseline;gap:8px;margin:8px 0 4px}
.quota-remaining{
  font-size:1.75rem;font-weight:700;line-height:1.15;
  font-variant-numeric:tabular-nums;color:var(--ink-strong);
}
.quota-of{font-size:.875rem;color:var(--muted)}
.quota-note{margin:0;font-size:.875rem;color:var(--muted);font-variant-numeric:tabular-nums}
.quota-bar{
  height:6px;border-radius:999px;background:var(--surface-sunken);
  margin:12px 0 10px;overflow:hidden;
}
.quota-bar-fill{
  display:block;height:100%;border-radius:999px;background:var(--indigo-solid);
}
.quota-hint{margin:0;font-size:.875rem;color:var(--muted);line-height:1.6;max-width:68ch}

@media (max-width:760px){
  .dash-head h1{font-size:1.5rem}
  .dash-card .stat-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .dash-card .stat-num{font-size:1.5rem}
  .dash-feed .ui-table td,
  .dash-feed .ui-table th{padding-left:14px;padding-right:14px}
}

/* --------------------------------------------------------------------------
   Pools list (/pools)
   The daily screen: a name that does not wrap mid-word, a quiet mode line,
   and one primary action per row. Secondary links stay as text so the row
   has a single visual weight.
   -------------------------------------------------------------------------- */
.pools-head h1{
  font-size:2rem;line-height:1.22;letter-spacing:-.015em;margin:0 0 8px;
}
.pools-head p{margin:0}
.pools-actions{display:flex;flex-wrap:wrap;gap:10px;margin:24px 0 0}
.pools-actions .button{min-height:44px;padding:0 16px;font-size:.875rem}
.pools-card{margin-top:24px;padding:0}
.pools-card .ui-table td,
.pools-card .ui-table th{padding-left:24px;padding-right:24px}
.pools-table td:first-child{min-width:220px}
.pool-name{font-weight:600;color:var(--ink-strong);overflow-wrap:anywhere}
.pool-meta{display:block;font-size:.875rem;color:var(--muted);margin-top:2px}
.pools-table .actions-cell{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;
  justify-content:flex-end;
}
.pools-table .actions-cell .button{min-height:40px;padding:0 14px;font-size:.875rem}
.pools-table .row-actions{
  display:inline-flex;flex-wrap:wrap;align-items:center;gap:6px 10px;
}
.pools-table .row-actions .link{
  color:var(--muted);font-size:.875rem;font-weight:600;
  text-decoration:none;white-space:nowrap;
}
.pools-table .row-actions .link:hover{color:var(--indigo);text-decoration:underline}
.pools-table .row-actions button.secondary{
  min-height:36px;padding:0 12px;font-size:.875rem;
  background:var(--surface);color:var(--ink-strong);border:1px solid var(--line-strong);
}
.pools-table .row-actions button.secondary:hover{border-color:var(--ink-strong)}
.pools-empty-action{margin:0 0 32px;text-align:center}

@media (max-width:760px){
  .pools-head h1{font-size:1.5rem}
  .pools-card .ui-table td,
  .pools-card .ui-table th{padding-left:14px;padding-right:14px}
  .pools-table td:first-child{min-width:0}
  .pools-table .actions-cell{justify-content:flex-start;margin-top:8px}
  .pools-actions .button{flex:1 1 auto}
}

/* --------------------------------------------------------------------------
   New pool (/pools/new), roll history (/pools/<id>/rolls), sessions
   -------------------------------------------------------------------------- */
.new-card{margin-top:20px;max-width:820px}
.new-card h2{font-size:1rem;font-weight:600;margin:0 0 18px}

/* A textarea and a file input are form controls too: give them the same
   border, radius and focus ring as an input rather than the browser default. */
.field textarea{
  width:100%;padding:12px 14px;
  border:1px solid var(--line-strong);border-radius:var(--r-ctl);
  font:inherit;font-size:1rem;background:var(--surface);color:var(--ink-strong);
  resize:vertical;min-height:120px;
}
.field textarea:focus{
  outline:none;border-color:var(--indigo);
  box-shadow:0 0 0 3px rgba(67,56,202,.14);
}
.field input[type="file"]{
  width:100%;min-height:48px;padding:10px 14px;
  border:1px solid var(--line-strong);border-radius:var(--r-ctl);
  font:inherit;font-size:.875rem;background:var(--surface);color:var(--muted);
}
.field select{
  min-height:48px;height:48px;width:100%;padding:0 12px;
  border:1px solid var(--line-strong);border-radius:var(--r-ctl);
  font:inherit;font-size:1rem;background:var(--surface);color:var(--ink-strong);
}
.field select:focus{
  outline:none;border-color:var(--indigo);
  box-shadow:0 0 0 3px rgba(67,56,202,.14);
}

.template-list{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));
  gap:12px;
}
.template-card{
  display:flex;flex-direction:column;gap:10px;
  border:1px solid var(--line-soft);border-radius:var(--r-card);
  padding:16px;background:var(--surface);height:100%;
}
.template-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;flex-wrap:wrap}
.template-card .name{font-weight:600;font-size:.875rem;color:var(--ink-strong)}
.template-count{font-size:.75rem;color:var(--muted);white-space:nowrap}
.template-desc{
  margin:0;font-size:.875rem;color:var(--muted);line-height:1.55;flex:1;
}
.template-card button{
  width:100%;min-height:40px;padding:0 14px;font-size:.875rem;
  background:var(--surface);color:var(--ink-strong);border:1px solid var(--line-strong);
}
.template-card button:hover{border-color:var(--ink-strong)}

.import-errors{
  background:#fef2f2;border:1px solid #fca5a5;border-radius:var(--r-ctl);
  padding:12px 14px;margin:0 0 18px;color:#7f1d1d;font-size:.875rem;
}
.import-errors p{margin:0 0 6px;font-weight:600}
.import-errors ul{margin:0;padding-left:20px}
.import-errors li{margin:3px 0;line-height:1.5}

/* Roll history keeps the pool bar (it is the page's context switcher) and
   puts the log in the shared table. */
.rolls-head h1{
  font-size:2rem;line-height:1.22;letter-spacing:-.015em;margin:8px 0;
  overflow-wrap:anywhere;
}
.rolls-head p{margin:0 0 20px;color:var(--muted)}
.rolls-card{padding:0;margin-top:8px}
.rolls-card .ui-table td,
.rolls-card .ui-table th{padding-left:24px;padding-right:24px}
.chain-mini{font-size:.875rem;color:var(--muted);margin-top:2px;overflow-wrap:anywhere}

/* Sessions list + create form */
.sessions-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:24px;align-items:start;margin-top:24px}
.sessions-grid .ui-card h2{font-size:1rem;font-weight:600;margin:0 0 16px}
.sessions-list{margin-top:24px}
.sessions-list .ui-card{padding:0}
.sessions-list .ui-table td,
.sessions-list .ui-table th{padding-left:24px;padding-right:24px}
.sessions-code{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:.875rem;font-weight:600;letter-spacing:.06em;
}
.sessions-list .ui-table .actions-cell{text-align:right}
.sessions-list .ui-table .actions-cell .button{
  min-height:36px;padding:0 12px;font-size:.875rem;
}

@media (max-width:900px){.sessions-grid{grid-template-columns:1fr}}
@media (max-width:760px){
  .rolls-head h1{font-size:1.5rem}
  .rolls-card .ui-table td,
  .rolls-card .ui-table th{padding-left:14px;padding-right:14px}
  .sessions-list .ui-table td,
  .sessions-list .ui-table th{padding-left:14px;padding-right:14px}
}

/* --------------------------------------------------------------------------
   Plan page (/plan)
   Status, then one comparison table, then two purchase cards. The table is
   the answer to "which plan" — the cards only repeat a column of it.
   -------------------------------------------------------------------------- */
.plan-head h1{
  font-size:2rem;line-height:1.22;letter-spacing:-.015em;margin:0 0 8px;
}
.plan-head p{margin:0}

.plan-status{margin-top:24px;max-width:720px}
.plan-status-label{
  font-size:.875rem;font-weight:600;color:var(--muted);
  text-transform:uppercase;letter-spacing:.05em;margin:0 0 10px;
}
.plan-status-tier{margin:0 0 8px}
.plan-status-note{margin:0;font-size:.875rem;color:var(--muted);line-height:1.6}
.plan-status-note b{color:var(--ink-strong);font-weight:600}

.plan-table td:first-child{font-weight:600;color:var(--ink-strong)}
.plan-table th.num{text-align:right}

.plan-choices{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:20px;margin-top:4px;
}
.plan-choice{
  display:flex;flex-direction:column;
  background:var(--surface);border:1px solid var(--line-soft);
  border-radius:var(--r-panel);padding:26px;
}
.plan-choice h3{font-size:1rem;font-weight:600;margin:0 0 10px}
.plan-choice-price{
  font-size:1.75rem;font-weight:700;line-height:1.2;
  letter-spacing:-.012em;margin:0 0 4px;
  font-variant-numeric:tabular-nums;color:var(--ink-strong);
}
.plan-choice-per{font-size:.875rem;font-weight:400;color:var(--muted);margin-left:6px}
.plan-choice .ui-plan-list{margin:18px 0 0}
.plan-choice-bonus{
  font-size:.875rem;color:var(--muted);margin:16px 0 0;
  padding-top:16px;border-top:1px solid var(--line-soft);
}
.plan-months{margin:20px 0 0}
.plan-choice button[type="submit"]{
  width:100%;min-height:48px;border-radius:var(--r-ctl);
  background:var(--indigo-solid);border:1px solid var(--indigo-solid);
  color:#fff;font-size:1rem;font-weight:600;
}
.plan-choice button[type="submit"]:hover{background:var(--indigo-deep)}
.plan-months-hint{
  margin:16px 0 0;font-size:.875rem;color:var(--muted);max-width:68ch;
}
.plan-verify{
  margin:16px 0 0;padding:16px 18px;
  background:#fef3c7;border-radius:var(--r-ctl);
  color:#78350f;font-size:.875rem;
}
.plan-verify p{margin:0}

@media (max-width:760px){
  .plan-head h1{font-size:1.5rem}
  .plan-choices{grid-template-columns:1fr}
  .plan-choice{padding:20px}
}

/* --------------------------------------------------------------------------
   Credits (/tama) and referrals
   -------------------------------------------------------------------------- */
.tama-balance{margin-top:24px;max-width:560px}
.tama-balance-label{
  font-size:.875rem;font-weight:600;color:var(--muted);
  text-transform:uppercase;letter-spacing:.05em;margin:0 0 8px;
}
.tama-balance-value{
  font-size:2rem;font-weight:700;line-height:1.2;letter-spacing:-.015em;
  margin:0;color:var(--ink-strong);font-variant-numeric:tabular-nums;
}
.tama-balance-value span{font-size:1rem;font-weight:600;color:var(--muted);margin-left:4px}
.tama-balance-note{margin:6px 0 0;font-size:.875rem;color:var(--muted)}

.tama-grid{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:24px;align-items:start;margin-top:24px;
}
.tama-grid .ui-card h2{font-size:1rem;font-weight:600;margin:0 0 16px}
.preset-label{
  font-size:.875rem;font-weight:600;color:var(--ink-strong);margin:0 0 8px;
}
.preset-row{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 20px}
.preset-row button{
  min-height:40px;padding:0 14px;font-size:.875rem;
  background:var(--surface);color:var(--ink-strong);border:1px solid var(--line-strong);
  border-radius:var(--r-ctl);font-weight:600;
}
.preset-row button:hover{background:var(--indigo-wash);border-color:var(--indigo-soft);color:var(--indigo-deep)}
.txn-note{max-width:34ch;overflow-wrap:anywhere}

/* Referral code and share link: the code is a value to copy, not prose. */
.ref-code-row{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:0 0 16px}
.ref-code{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:1.25rem;font-weight:700;letter-spacing:.08em;color:var(--ink-strong);
}
.ref-copy{
  min-height:40px;padding:0 14px;background:var(--surface);color:var(--ink-strong);
  border:1px solid var(--line-strong);border-radius:var(--r-ctl);
  font-size:.875rem;font-weight:600;
}
.ref-copy:hover{border-color:var(--ink-strong)}
.ref-link-row{
  display:flex;flex-wrap:wrap;align-items:center;gap:10px;
  margin:0 0 18px;padding:12px 14px;
  background:var(--canvas);border:1px solid var(--line-soft);
  border-radius:var(--r-ctl);
}
.ref-link-row code{
  flex:1;min-width:0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:.875rem;color:var(--muted);overflow-wrap:anywhere;
}
.ref-counts{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 14px}
.ref-total{margin:0 0 18px;font-size:.875rem;color:var(--muted)}
.ref-total b{color:var(--ink-strong);font-size:1rem;font-variant-numeric:tabular-nums}
.ref-notes{margin:0;padding:0;list-style:none;display:grid;gap:6px}
.ref-notes li{font-size:.875rem;color:var(--muted);line-height:1.6}

@media (max-width:900px){.tama-grid{grid-template-columns:1fr}}

/* --------------------------------------------------------------------------
   Profile settings (/user)
   Four stacked cards: verification, photo, identity, public preview. Each is
   capped at 720px so a form field never stretches across the whole canvas.
   -------------------------------------------------------------------------- */
.profile-card{margin-top:20px;max-width:720px}
.profile-card h2{font-size:1rem;font-weight:600;margin:0 0 16px}
.profile-photo-row{display:flex;gap:20px;align-items:flex-start;flex-wrap:wrap}
.profile-photo-actions{flex:1;min-width:240px}
.profile-avatar-empty{
  background:var(--canvas);border:1px dashed var(--line-strong);
}
.profile-photo-actions .field{margin:0}
.profile-photo-actions button.danger{
  min-height:44px;padding:0 16px;border-radius:var(--r-ctl);
  background:var(--surface);color:var(--danger-ink);
  border:1px solid var(--danger-ink);font-size:.875rem;font-weight:600;
}
.profile-photo-actions button.danger:hover{background:#fef2f2}
.share-block{border-top:1px solid var(--line-soft);padding-top:18px;margin-top:18px}
.share-block:first-of-type{border-top:0;padding-top:0;margin-top:0}
.share-block h3{font-size:.875rem;font-weight:600;margin:0 0 10px;overflow-wrap:anywhere}
.share-qr-row{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.share-qr-row .qr-thumb{width:88px;height:88px;border:1px solid var(--line-soft);border-radius:8px;background:var(--surface);padding:4px}

@media (max-width:760px){
  .profile-photo-row{gap:14px}
  .profile-photo-actions{min-width:0;flex:1 1 100%}
}

/* --------------------------------------------------------------------------
   Pool editor (/pools/<id>)
   The daily screen for a publisher: header, action row, then the item list.
   Settings, advanced, import/export and the log stay folded — the editor is
   long by nature and the folds are what keep it usable.
   -------------------------------------------------------------------------- */
.editor-page{max-width:1120px}
.editor-head{margin-bottom:28px}
.editor-head h1{
  display:flex;align-items:center;flex-wrap:wrap;gap:10px;
  font-size:2rem;line-height:1.22;letter-spacing:-.015em;
  margin:0 0 8px;overflow-wrap:anywhere;
}
.editor-meta{font-size:.875rem;color:var(--muted);margin:0 0 8px}
.editor-desc{max-width:68ch;margin:0 0 8px;font-size:1rem;line-height:1.6;overflow-wrap:anywhere}
/* The action row keeps the literal class="actions" the tests pin; styling
   hangs off the page wrapper instead of a new class. */
.editor-page .actions{display:flex;flex-wrap:wrap;gap:10px;margin:20px 0 0;align-items:center}
.editor-page .actions .button{min-height:44px;padding:0 16px;font-size:.875rem}

/* Folds: the summary is the control, so it needs a 44px hit area and a clear
   open/closed marker. */
.editor-page .editor-fold{margin-top:16px}
.editor-page .editor-fold > summary{
  min-height:44px;padding:4px 0;
}
.editor-page .editor-fold .editor-fold-title{font-size:1rem;font-weight:600}
.editor-page .card{margin-top:16px}
.editor-page .card h2{font-size:1rem;font-weight:600;margin:0 0 16px}
.editor-page .card h3{font-size:.875rem;font-weight:600;margin:0 0 10px}

/* Item rows in the editor: the public page's row styles are scoped to
   .pool-items, so these are the editor's own. */
.editor-page .item-list{display:grid;gap:12px;margin-top:4px}
.editor-page .item-card{
  border:1px solid var(--line-soft);border-radius:var(--r-card);
  padding:16px;background:var(--surface);
}
.editor-page .item-main{display:flex;gap:14px;align-items:flex-start}
.editor-page .item-thumb{
  width:64px;height:64px;flex:0 0 64px;border-radius:8px;
  border:1px solid var(--line-soft);background:var(--canvas);
  display:flex;align-items:center;justify-content:center;overflow:hidden;
}
.editor-page .item-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.editor-page .item-thumb span{font-size:.75rem;color:var(--muted);text-align:center;padding:0 4px}
.editor-page .item-info{flex:1;min-width:0}
.editor-page .item-info .name{font-weight:600;font-size:1rem;overflow-wrap:anywhere}
.editor-page .item-edit{margin-top:10px;border-top:1px solid var(--line-soft);padding-top:10px}
.editor-page .item-edit summary{
  cursor:pointer;color:var(--indigo);font-size:.875rem;font-weight:600;
  list-style:none;min-height:32px;display:flex;align-items:center;
}
.editor-page .item-edit summary::-webkit-details-marker{display:none}
.editor-page .item-edit summary::before{content:"+ ";font-weight:700}
.editor-page .item-edit[open] summary::before{content:"— "}

/* Add-item tier picker: radios as chips, one row. */
.editor-page .tier-options{display:flex;flex-wrap:wrap;gap:8px;margin:6px 0 0}
.editor-page .tier-opt{
  display:inline-flex;align-items:center;gap:6px;
  min-height:36px;padding:0 12px;
  border:1px solid var(--line-strong);border-radius:999px;
  background:var(--surface);font-size:.875rem;cursor:pointer;
}
.editor-page .tier-opt:has(input:checked){
  border-color:var(--indigo);background:var(--indigo-wash);color:var(--indigo-deep);
  font-weight:600;
}
.editor-page .tier-opt input{accent-color:var(--indigo)}

/* Bulk table inside its fold. */
.editor-page .bulk-form{margin-top:14px}
.editor-page .item-table{width:100%;border-collapse:collapse}
.editor-page .item-table th{
  font-size:.875rem;font-weight:600;color:var(--muted);text-align:left;
  padding:8px 10px;border-bottom:1px solid var(--line-soft);white-space:nowrap;
}
.editor-page .item-table td{
  padding:8px 10px;border-bottom:1px solid var(--line-soft);vertical-align:middle;
}
.editor-page .item-table input,
.editor-page .item-table select{
  width:100%;max-width:100%;min-height:40px;height:40px;
  padding:0 10px;border:1px solid var(--line-strong);
  border-radius:var(--r-ctl);font:inherit;font-size:.875rem;background:var(--surface);
}
.editor-page .item-table input[type="number"]{text-align:right;font-variant-numeric:tabular-nums}
.editor-page .bulk-actions{display:flex;flex-wrap:wrap;gap:12px;align-items:center;margin:16px 0 0}
.editor-page .item-cell{display:flex;align-items:center;gap:10px;min-width:0}
.editor-page .item-thumb-sm{width:36px;height:36px;border-radius:6px;object-fit:cover;flex:0 0 36px}

/* Danger zone: outline only, never a solid red block next to Save. */
.editor-page .danger-zone{margin-top:16px;border-top:1px solid var(--line-soft);padding-top:14px}
.editor-page .danger-zone > summary{
  cursor:pointer;color:var(--danger-ink);font-size:.875rem;font-weight:600;
}
.editor-page button.danger{
  min-height:44px;padding:0 16px;border-radius:var(--r-ctl);
  background:var(--surface);color:var(--danger-ink);
  border:1px solid var(--danger-ink);font-size:.875rem;font-weight:600;
}
.editor-page button.danger:hover{background:#fef2f2}

@media (max-width:760px){
  .editor-head h1{font-size:1.5rem}
  .editor-page .actions .button{flex:1 1 auto}
  .editor-page .item-table thead{display:none}
  .editor-page .item-table,
  .editor-page .item-table tbody,
  .editor-page .item-table tr,
  .editor-page .item-table td{display:block;width:100%}
  .editor-page .item-table tr{
    border:1px solid var(--line-soft);border-radius:var(--r-card);
    margin-bottom:10px;padding:8px 12px;
  }
  .editor-page .item-table td{
    border:0;padding:5px 0;display:grid;
    grid-template-columns:7rem 1fr;align-items:center;gap:.4rem;
  }
  .editor-page .item-table td::before{
    content:attr(data-label);font-size:.875rem;color:var(--muted);
  }
  .editor-page .item-table td[data-label=""]{display:block}
}

/* --------------------------------------------------------------------------
   Run pull (/pools/<id>/pull)
   One narrow card holds the only primary action; the odds preview follows.
   -------------------------------------------------------------------------- */
.pull-page{max-width:1120px}
.pull-run{max-width:520px}
.pull-run .ui-card h2{font-size:1rem;font-weight:600;margin:0 0 14px}
.pull-balance{
  font-size:.875rem;color:var(--muted);margin:0 0 20px;
  padding-bottom:16px;border-bottom:1px solid var(--line-soft);
}
.pull-balance b{
  color:var(--ink-strong);font-weight:600;font-size:1rem;
  font-variant-numeric:tabular-nums;
}
.pull-total{
  margin:0;font-size:.875rem;color:var(--muted);
  font-variant-numeric:tabular-nums;
}
/* Batch confirmation: a warning wash with a worded heading, never red alone. */
.confirm-block{
  margin:18px 0 0;padding:16px 18px;
  background:#fef3c7;border:1px solid #fcd34d;
  border-radius:var(--r-ctl);
}
.confirm-heading{
  margin:0 0 8px;font-size:.875rem;font-weight:700;color:#78350f;
}
.confirm-text{margin:0 0 12px;font-size:.875rem;color:#78350f;line-height:1.6}
.confirm-check{
  display:flex;gap:10px;align-items:flex-start;
  font-size:.875rem;color:#78350f;line-height:1.5;cursor:pointer;
}
.confirm-check input{
  width:20px;height:20px;margin:1px 0 0;flex:0 0 20px;
  accent-color:var(--indigo);
}
.pull-run button[type="submit"]{
  width:100%;min-height:48px;border-radius:var(--r-ctl);
  background:var(--indigo-solid);border:1px solid var(--indigo-solid);
  color:#fff;font-size:1rem;font-weight:600;
}
.pull-run button[type="submit"]:hover{background:var(--indigo-deep)}
.pull-run button[type="submit"][disabled]{
  background:var(--canvas);color:var(--muted);border-color:var(--line-soft);
  cursor:not-allowed;
}

/* --------------------------------------------------------------------------
   Admin console (/admin)
   Scoped to .admin-page: the console shares class names with admin_users.html
   and the pool editor (.check-row, .adjust-form), so nothing here is global.
   The tab strip keeps its own rules in style.css — the audit test pins the
   exact strings there.
   -------------------------------------------------------------------------- */
.admin-page{max-width:1120px;padding:40px 0 24px}
.admin-page h1{
  font-size:2rem;line-height:1.22;letter-spacing:-.015em;margin:0 0 20px;
}
.admin-page .tab-panel > .card{margin-top:20px}
.admin-page .card h2{font-size:1rem;font-weight:600;margin:0 0 14px}
.admin-page .card h3{
  font-size:.875rem;font-weight:600;margin:28px 0 12px;
  padding-top:18px;border-top:1px solid var(--line-soft);
}
.admin-page .card h4{
  font-size:.875rem;font-weight:600;margin:18px 0 8px;color:var(--muted);
}

/* Settings grid: label above input, never a cramped two-column row. */
.admin-page .settings-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));
  gap:14px 16px;margin:0 0 16px;
}
.admin-page .settings-grid > label{
  display:grid;gap:6px;font-size:.875rem;font-weight:600;
  color:var(--ink-strong);min-width:0;
}
.admin-page .settings-grid input{
  width:100%;box-sizing:border-box;min-height:44px;height:44px;
  padding:0 12px;border:1px solid var(--line-strong);
  border-radius:var(--r-ctl);font:inherit;font-size:.875rem;
  background:var(--surface);color:var(--ink-strong);
}
.admin-page .settings-grid input:focus{
  outline:none;border-color:var(--indigo);
  box-shadow:0 0 0 3px rgba(67,56,202,.14);
}

/* Data tables inside the console. */
.admin-page .table-wrap{width:100%;overflow-x:auto}
.admin-page table{width:100%;border-collapse:collapse;font-size:.875rem;background:var(--surface)}
.admin-page th{
  font-size:.75rem;font-weight:600;color:var(--muted);text-align:left;
  padding:10px 12px;border-bottom:1px solid var(--line-soft);
  white-space:nowrap;text-transform:uppercase;letter-spacing:.04em;
}
.admin-page td{
  padding:12px;border-bottom:1px solid var(--line-soft);vertical-align:top;
}
.admin-page tr:last-child td{border-bottom:0}
.admin-page td.num,
.admin-page th.num{text-align:right;font-variant-numeric:tabular-nums}
.admin-page .detail-cell{
  max-width:34ch;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:.75rem;color:var(--muted);overflow-wrap:anywhere;
}
.admin-page td code,
.admin-page td .mono{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.8125rem;
}

/* Inline action forms: a select/input plus a button on one line. */
.admin-page .attach-form,
.admin-page .adjust-form{
  display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:0;
}
.admin-page .attach-form select,
.admin-page .adjust-form input{
  min-height:40px;height:40px;padding:0 10px;max-width:220px;
  border:1px solid var(--line-strong);border-radius:var(--r-ctl);
  font:inherit;font-size:.875rem;background:var(--surface);
}
.admin-page .attach-form button,
.admin-page .adjust-form button{
  min-height:40px;padding:0 14px;font-size:.875rem;
}
.admin-page .search-row{
  display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:0 0 8px;
}
.admin-page .search-row input,
.admin-page .search-row select{
  min-height:44px;height:44px;padding:0 12px;flex:1 1 200px;min-width:0;
  border:1px solid var(--line-strong);border-radius:var(--r-ctl);
  font:inherit;font-size:.875rem;background:var(--surface);
}
.admin-page .search-row button{min-height:44px;padding:0 16px;font-size:.875rem}

/* Float alert: a wash with a worded line, not a colour-only warning. */
.admin-page .float-line{margin:0;font-size:.875rem;line-height:1.6}
.admin-page .card.alert{
  border-color:var(--warn-line);background:var(--warn-bg);
}
.admin-page .card.alert h2{color:var(--warn-ink)}
.admin-page .float-line.over{color:var(--warn-ink);font-weight:600}

.admin-page .check-row{
  display:flex;gap:10px;align-items:flex-start;margin:0 0 8px;
  font-size:.875rem;
}
.admin-page .check-row input{
  width:20px;height:20px;margin:1px 0 0;flex:0 0 20px;
  accent-color:var(--indigo);
}
.admin-page .check-text{line-height:1.5}
.admin-page textarea{
  width:100%;padding:12px 14px;min-height:88px;
  border:1px solid var(--line-strong);border-radius:var(--r-ctl);
  font:inherit;font-size:.875rem;background:var(--surface);resize:vertical;
}
.admin-page textarea:focus{
  outline:none;border-color:var(--indigo);
  box-shadow:0 0 0 3px rgba(67,56,202,.14);
}
.admin-page select{
  min-height:44px;height:44px;padding:0 10px;
  border:1px solid var(--line-strong);border-radius:var(--r-ctl);
  font:inherit;font-size:.875rem;background:var(--surface);color:var(--ink-strong);
}
.admin-page button.danger{
  min-height:40px;padding:0 14px;border-radius:var(--r-ctl);
  background:var(--surface);color:var(--danger-ink);
  border:1px solid var(--danger-ink);font-size:.875rem;font-weight:600;
}
.admin-page button.danger:hover{background:#fef2f2}

@media (max-width:760px){
  .admin-page{padding:32px 0 16px}
  .admin-page h1{font-size:1.5rem}
  .admin-page .settings-grid{grid-template-columns:1fr}
}

/* --------------------------------------------------------------------------
   Notice strip (operator message)
   -------------------------------------------------------------------------- */
.notice-strip{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:.5rem;
  background:var(--indigo-wash);
  border:1px solid var(--indigo-soft);
  border-radius:var(--r-ctl);
  padding:10px 14px;
  margin:24px 0 0;
}
.notice-strip strong{font-size:.875rem;color:var(--ink-strong)}
.notice-strip .prose{flex:1 1 14rem;min-width:0;font-size:.875rem;color:var(--muted)}
.notice-strip .prose p{margin:0}

/* --------------------------------------------------------------------------
   Motion — the hero cards float only when the visitor allows it.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  .hero-item{animation:none}
}
