/* ==========================================================================
   BidPage design tokens — the single source of truth for spacing, radius,
   elevation and type. Pages should use these, not ad-hoc pixel values.
   ========================================================================== */
:root{
  /* palette */
  --baize:#0E3B2E; --gold:#E8A63A; --ivory:#FAF6EE; --ink:#132019;
  --muted:#5c6b62; --line:#e4ddd0; --danger:#b3402e; --ok:#1f7a4d;
  --baize-tint:rgba(14,59,46,.04); --gold-tint:rgba(232,166,58,.14);
  --ivory-deep:#F3EFE7;   /* page ivory darkened ~3%, for the hero stage */
  --teal:#7FBFC9; --lavender:#B9A7DC; --coral:#E8836B;

  /* spacing scale — 4 / 8 / 12 / 16 / 24 / 32 */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px;

  /* radius */
  --r-input:10px; --r-card:14px; --r-pill:999px;

  /* one soft card shadow, used everywhere or not at all */
  --shadow:0 1px 2px rgba(19,32,25,.04), 0 4px 16px rgba(19,32,25,.05);

  /* type: Space Grotesk for display and numbers, Inter for body */
  --display:'Space Grotesk',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --body:'Inter',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --t-display:clamp(1.9rem,5vw,2.8rem);
  --t-title:1.35rem;
  --t-heading:1.05rem;
  --t-body:1rem;
  --t-caption:.85rem;
}

*{box-sizing:border-box;margin:0}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{
  font-family:var(--body);font-size:var(--t-body);color:var(--ink);
  background:var(--ivory);line-height:1.55;
  /* iOS notch / home indicator */
  padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);
}
.wrap{max-width:680px;margin:0 auto;padding:var(--s5) var(--s4)}
/* The homepage runs one 1000px grid for every section so the hero and the body
   share a left edge. Prose inside those sections keeps the 680px measure via
   .measure — a paragraph set across 1000px is not readable. */
.wrap--wide{max-width:1000px;padding-top:0}
.measure{max-width:680px}
header.site{display:flex;align-items:center;gap:var(--s2);
  padding:var(--s4) var(--s4) var(--s2);padding-top:calc(var(--s4) + env(safe-area-inset-top))}
header.site img{height:34px}

h1,h2,h3,.price,.count,.num{font-family:var(--display);letter-spacing:-.01em}
h1{font-size:var(--t-display);line-height:1.12}
h2{font-size:var(--t-title)}
h3{font-size:var(--t-heading)}
.eyebrow{font-family:var(--display);font-size:.8rem;text-transform:uppercase;
  letter-spacing:.12em;color:var(--muted)}
.muted{color:var(--muted);font-size:.92rem}
.caption{color:var(--muted);font-size:var(--t-caption);line-height:1.45}
.error{color:var(--danger);font-weight:600}
.num,.value{font-variant-numeric:tabular-nums}

/* ---- cards: one recipe -------------------------------------------------- */
.card{background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  padding:var(--s5) var(--s4);margin:var(--s4) 0;box-shadow:var(--shadow)}
.card > h3{margin-bottom:var(--s2)}
.card-header{display:flex;align-items:flex-start;justify-content:space-between;
  gap:var(--s3);margin-bottom:var(--s3)}
.card-header h3{margin:0;min-width:0}
.card-header .pill{flex:0 0 auto}
.card-quiet{background:var(--ivory);box-shadow:none}
/* Launch-asset treatment: a thin coloured top edge on the card. */
.card-accent{border-top:3px solid var(--gold);padding-top:calc(var(--s5) - 3px)}
.danger-card{border-color:var(--danger);background:rgba(179,64,46,.05);box-shadow:none}
.ready-card{border-color:var(--ok);background:rgba(31,122,77,.06);box-shadow:none}
.ready-card h3{color:var(--ok)}
.ready-tick{font-weight:700}
.danger-card h3{color:var(--danger)}
.action-card{border-color:var(--gold);background:var(--gold-tint);box-shadow:none}

/* ---- pills: semantic, not decorative ------------------------------------ */
.pill{display:inline-block;border-radius:var(--r-pill);padding:var(--s1) var(--s3);
  font-size:.8rem;font-family:var(--display);font-weight:600;white-space:nowrap;
  background:var(--baize);color:var(--ivory)}
.pill.gold,.pill--pending{background:var(--gold);color:var(--ink)}
.pill--live{background:var(--baize);color:var(--ivory)}
.pill--done{background:var(--ok);color:#fff}
.pill--dead{background:var(--line);color:var(--muted)}

/* ---- buttons: 44px minimum tap target ----------------------------------- */
.btn{display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;font-family:var(--display);font-weight:600;border:0;
  border-radius:var(--r-input);padding:var(--s3) var(--s5);font-size:var(--t-body);
  cursor:pointer;text-decoration:none;text-align:center}
.btn-primary{background:var(--baize);color:var(--ivory)}
.btn-gold{background:var(--gold);color:var(--ink)}
.btn-ghost{background:transparent;border:1px solid var(--line);color:var(--ink)}
.btn-ghost:hover{border-color:var(--baize)}
.btn-danger{background:var(--danger);color:#fff}

/* Segmented close-time presets on /new. The chosen one is filled, not merely
   outlined, so the state survives a glance on a phone. */
.preset-row{display:flex;flex-wrap:wrap;gap:var(--s2)}
.preset{font-family:var(--display);font-weight:600;font-size:.9rem;
  background:#fff;color:var(--ink);border:1px solid var(--line);
  border-radius:var(--r-pill);padding:10px var(--s4);min-height:44px;cursor:pointer;
  transition:border-color .12s,background-color .12s,color .12s}
.preset:hover{border-color:var(--baize)}
.preset.is-on{background:var(--baize);border-color:var(--baize);color:var(--ivory)}

/* Checkbox + label on one baseline, with the 44px target kept on the row. */
.check{display:flex;align-items:flex-start;gap:var(--s3);cursor:pointer;
  min-height:44px;padding:var(--s2) 0}
.check input{width:20px;height:20px;flex:0 0 auto;margin:2px 0 0;accent-color:var(--baize)}

/* Labelled switch. The WORDS carry the state — "Listed on bidpage.app" vs "Private
   link only" — and the track colour only agrees with them, so the control still reads
   correctly in greyscale or to someone who cannot separate baize from grey. */
.switch{display:flex;align-items:center;gap:var(--s3);cursor:pointer;
  min-height:44px;padding:var(--s2) 0}
.switch input{position:absolute;opacity:0;width:0;height:0}
.switch__track{position:relative;flex:0 0 auto;width:44px;height:26px;border-radius:var(--r-pill);
  background:var(--line);transition:background-color .15s ease}
.switch__knob{position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;
  background:#fff;box-shadow:0 1px 3px rgba(19,32,25,.3);transition:transform .15s ease}
.switch input:checked + .switch__track{background:var(--baize)}
.switch input:checked + .switch__track .switch__knob{transform:translateX(18px)}
.switch input:focus-visible + .switch__track{outline:2px solid var(--baize);outline-offset:2px}
.switch__text{font-family:var(--display);font-weight:600;font-size:.92rem}
.switch input:disabled + .switch__track{opacity:.5}
.switch:has(input:disabled){cursor:not-allowed;opacity:.75}

/* Bid + Buy Now sit on one row where there is space and stack on a phone, rather
   than relying on a left margin that collapsed at narrow widths. */
.bid-actions{display:flex;flex-wrap:wrap;gap:var(--s3);margin-top:var(--s3)}
.bid-actions .btn{flex:1 1 auto}

/* Phone-only bid bar. A live auction's price and its way in stay reachable without
   scrolling back up; desktop has both in view already. */
.bidbar{display:none}
@media (max-width:699px){
  .bidbar{position:fixed;left:0;right:0;bottom:0;z-index:30;
    display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
    padding:var(--s3) var(--s4);
    padding-bottom:calc(var(--s3) + env(safe-area-inset-bottom));
    background:rgba(250,246,238,.94);border-top:1px solid var(--line);
    box-shadow:0 -2px 12px rgba(19,32,25,.08)}
  @supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
    .bidbar{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}
  }
  .bidbar__info{display:flex;flex-direction:column;line-height:1.2;min-width:0}
  .bidbar__info b{font-family:var(--display);font-size:1.1rem;
    font-variant-numeric:tabular-nums}
  .bidbar__info span{font-size:var(--t-caption);color:var(--muted);
    font-variant-numeric:tabular-nums}
  .bidbar .btn{margin:0;flex:0 0 auto}
  /* clear the bar so it never covers the footer or the last card */
  body.has-bidbar footer{padding-bottom:calc(var(--s6) + 76px + env(safe-area-inset-bottom))}
}
.btn[disabled]{opacity:.5;cursor:not-allowed}
.btn-block{display:flex;width:100%}

/* ---- forms -------------------------------------------------------------- */
input,select,textarea{
  width:100%;padding:var(--s3);border:1px solid var(--line);border-radius:var(--r-input);
  font-family:inherit;
  /* 16px minimum or iOS Safari zooms the page on focus */
  font-size:max(16px,var(--t-body));
  background:#fff;margin:var(--s1) 0 var(--s3);min-height:44px}
textarea{min-height:96px}
label{font-weight:600;font-size:.92rem}
.field{margin:var(--s5) 0 0}
.field:first-child{margin-top:0}
.field > label{display:block;margin:0 0 var(--s2)}
.field > input,.field > textarea,.field > select{margin:0}
.field--section{margin-top:var(--s6)}
.help{color:var(--muted);font-size:var(--t-caption);line-height:1.45;margin:var(--s2) 0 0}
/* A hint belonging to the field above sits tight against it — the input already
   carries its own bottom margin — and anything following the hint gets its own gap. */
input + .help{margin-top:0}
.help + .btn{margin-top:var(--s3)}
form > .card{margin:var(--s5) 0 0}
form > .btn{margin-top:var(--s5)}

/* ---- label / value rows: the one row utility ---------------------------- */
.rows{list-style:none;padding:0;margin:var(--s3) 0 0;border-top:1px solid var(--line)}
.row{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3);
  padding:var(--s3) 0;border-bottom:1px solid var(--line);font-size:.92rem;list-style:none}
.row > :first-child{color:var(--muted)}
.row > :last-child{text-align:right;font-variant-numeric:tabular-nums}
.row--total{border-bottom:0;font-weight:700;font-family:var(--display)}
.rows .row:last-child{border-bottom:0}

/* ---- auction type cards ------------------------------------------------- */
.format-cards{display:grid;gap:var(--s3)}
.format-card{position:relative;display:block;width:100%;background:#fff;
  border:1px solid var(--line);border-radius:var(--r-card);padding:var(--s4);
  cursor:pointer;transition:border-color .12s,background-color .12s}
.format-card input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
.format-card .format-title{display:block;font-family:var(--display);font-weight:600;
  font-size:var(--t-body);line-height:1.3;padding-right:var(--s6)}
.format-card .format-desc{display:block;color:var(--muted);font-size:.88rem;
  font-weight:400;line-height:1.45;margin-top:var(--s1);padding-right:var(--s6)}
.format-card:hover{border-color:var(--baize)}
/* Homepage cards are entry points into the create form, so they carry the usual
   link affordances. They were static only while they did nothing. */
a.format-card--link{text-decoration:none;color:inherit;cursor:pointer}
.format-card--link:hover{border-color:var(--baize)}
.format-card--link:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
/* The hint reads on every card at rest — a hover-only reveal cannot tell a touch
   user, or a scanning eye, that the cards are clickable at all. */
.format-cta{display:block;margin-top:var(--s2);font-family:var(--display);font-weight:600;
  font-size:.8rem;color:var(--muted);transition:color .15s ease}
.format-card--link:hover .format-cta,
.format-card--link:focus-visible .format-cta{color:var(--baize)}
.format-card--accent:hover .format-cta,
.format-card--accent:focus-visible .format-cta{color:var(--gold)}
.format-card--link:hover,
.format-card--link:focus-visible{border-color:var(--baize);background:var(--baize-tint)}
@media (prefers-reduced-motion:no-preference){
  .format-card--link{transition:border-color .15s ease,background-color .15s ease,
    transform .15s ease,box-shadow .15s ease}
  .format-card--link:hover,
  .format-card--link:focus-visible{transform:translateY(-2px);box-shadow:var(--shadow)}
}
.format-card:has(input:checked){border-color:var(--baize);background:var(--baize-tint);
  box-shadow:inset 0 0 0 1px var(--baize)}
.format-card:has(input:checked) .format-title{color:var(--baize)}
.format-card:has(input:focus-visible){outline:2px solid var(--gold);outline-offset:2px}
.format-card--accent .format-title,
.format-card--accent:has(input:checked) .format-title{color:var(--gold)}
.format-check{position:absolute;top:var(--s4);right:var(--s4);width:22px;height:22px;
  border-radius:50%;background:var(--baize);color:var(--ivory);font-size:.7rem;
  line-height:1;display:none;place-items:center}
.format-card:has(input:checked) .format-check{display:grid}
.format-card--accent:has(input:checked) .format-check{background:var(--gold);color:var(--ink)}

/* ---- lifecycle stepper -------------------------------------------------- */
.stepper{display:flex;gap:0;margin:var(--s4) 0 0;padding:var(--s2) 0 0;list-style:none;
  overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.stepper::-webkit-scrollbar{display:none}
.step{flex:1 1 0;min-width:76px;text-align:center;position:relative;padding:0 2px}
/* connector sits behind the dot */
.step::before{content:'';position:absolute;top:13px;left:-50%;width:100%;height:2px;
  background:var(--line);z-index:0}
.step:first-child::before{display:none}
.step.is-done::before,.step.is-current::before,.step.is-skipped::before{background:var(--baize)}
/* A milestone that never happened on an auction that still progressed past it: the
   dot stays hollow, but the path through it is unbroken. */
.step.is-skipped .step-dot{border-style:dashed}
.step-dot{position:relative;z-index:1;width:26px;height:26px;margin:0 auto var(--s2);
  border-radius:50%;display:grid;place-items:center;
  border:2px solid var(--line);background:var(--ivory);
  font-size:.7rem;line-height:1;color:transparent}
.step.is-done .step-dot{background:var(--baize);border-color:var(--baize);color:var(--ivory)}
.step.is-current .step-dot{border-color:var(--gold);background:#fff;box-shadow:0 0 0 4px var(--gold-tint)}
.step-label{display:block;font-family:var(--display);font-size:.78rem;font-weight:600;
  line-height:1.25;color:var(--muted)}
.step.is-done .step-label,.step.is-current .step-label{color:var(--ink)}
.step-time{display:block;font-size:.7rem;color:var(--muted);margin-top:2px;
  font-variant-numeric:tabular-nums}
@media (prefers-reduced-motion:no-preference){
  .step.is-current .step-dot{animation:pulse 2.2s ease-in-out infinite}
  @keyframes pulse{
    0%,100%{box-shadow:0 0 0 4px var(--gold-tint)}
    50%{box-shadow:0 0 0 7px rgba(232,166,58,.22)}
  }
}
/* ---- guide stepper: the marketing diagram ---------------------------------
   Bigger numbered circles in the launch-asset accent palette. This variant is for
   the homepage only — the auction page's stepper keeps the strict baize/gold status
   colours, because there a dot's colour means something. */
.stepper--guide{align-items:flex-start;list-style:none}
.stepper--guide .step{min-width:0}
.stepper--guide .step-dot{
  width:40px;height:40px;border:0;background:var(--line);
  font-family:var(--display);font-weight:600;font-size:1rem;color:var(--ink);
  margin-bottom:var(--s3)}
.stepper--guide .step::before{top:19px}
/* Four launch accents cycling across six steps. */
.stepper--guide .step:nth-child(4n+1) .step-dot{background:#E8A63A}
.stepper--guide .step:nth-child(4n+2) .step-dot{background:var(--teal)}
.stepper--guide .step:nth-child(4n+3) .step-dot{background:var(--lavender)}
.stepper--guide .step:nth-child(4n+4) .step-dot{background:var(--coral)}
.stepper--guide .step-label{font-size:.82rem;color:var(--ink)}
.step-desc{display:block;font-size:.72rem;color:var(--muted);line-height:1.35;
  margin-top:var(--s1)}
/* Six columns with a sentence each do not fit a phone, so below this the journey
   runs downward instead — every step visible, no horizontal scrolling to discover. */
@media (max-width:599px){
  .stepper--guide{flex-direction:column;gap:0;overflow:visible}
  .stepper--guide .step{display:grid;grid-template-columns:32px 1fr;
    column-gap:var(--s3);text-align:left;padding:0 0 var(--s4) 0;min-width:0}
  .stepper--guide .step:last-child{padding-bottom:0}
  .stepper--guide .step::before{content:'';position:absolute;left:15px;top:32px;
    width:2px;height:calc(100% - 32px);background:var(--line)}
  /* Vertical: the line runs downward from each dot, so the first step needs one and
     the last does not — the opposite of the horizontal rule it inherits. */
  .stepper--guide .step:first-child::before{display:block}
  .stepper--guide .step:last-child::before{display:none}
  .stepper--guide .step-dot{grid-row:1 / span 2;width:32px;height:32px;
    margin:0;font-size:.88rem}
  .stepper--guide .step-label{grid-column:2;font-size:.92rem;align-self:center}
  .stepper--guide .step-desc{grid-column:2;font-size:.84rem;margin-top:2px}
}

@media (max-width:420px){
  .step{min-width:46px}
  .step-dot{width:20px;height:20px}
  .step::before{top:10px}
  .step-label{font-size:.66rem;letter-spacing:-.02em;word-break:break-word}
  .step-time{font-size:.65rem}
}

/* ---- legal documents (terms, privacy) ---------------------------------- */
.legal h2{margin:var(--s5) 0 var(--s2)}
.legal h3{margin:var(--s4) 0 var(--s1);font-size:var(--t-heading)}
.legal p,.legal li{font-size:.93rem}
.legal ol,.legal ul{padding-left:var(--s5);margin:var(--s2) 0}
.legal li{margin:var(--s1) 0}
.legal h1{font-size:var(--t-title)}

/* ---- misc --------------------------------------------------------------- */
.price{font-size:2.2rem;color:var(--baize);font-variant-numeric:tabular-nums}
.price small{font-size:1rem;color:var(--muted);font-family:var(--body)}
.count{font-variant-numeric:tabular-nums}
.hero{margin:0 0 var(--s4);border-radius:var(--r-card)}
.share-row{display:flex;flex-wrap:wrap;gap:var(--s3);margin-top:var(--s4)}
.btn-gold:hover{filter:brightness(1.03)}

/* ==========================================================================
   HOMEPAGE — two content layers with deliberately different grammar.
   REAL (.feature-card, .show-card): full colour, live, interactive, links out.
   ILLUSTRATIVE (.example-card): muted, chipped "Example", no numbers that could
   be mistaken for an outcome. Never blur the two.
   ========================================================================== */

/* The hero lives outside .wrap so its columns can exceed the 680px reading measure;
   .hero-inner re-centres it. Stacked by default — two columns only once there is room
   for a 400px card beside text that is still a comfortable measure. */
/* Full-bleed stage behind the 1000px grid: the page ivory deepened a touch plus a
   hairline, so the hero reads as composed without introducing a colour. */
.hero-block{padding:0;background:var(--ivory-deep)}
/* No border-bottom of its own: .proof sits flush beneath and already draws a
   border-top, so the stage would otherwise end in a doubled 2px rule. */
.hero-inner{max-width:1000px;margin:0 auto;padding:40px var(--s4) var(--s6)}
/* no featured auction to show: fall back to the page's own measure */
.hero-inner.is-solo{max-width:680px}
.hero-sub{font-size:1.05rem;color:var(--muted);margin:var(--s3) 0 var(--s5);max-width:34em}
.btn-lg{padding:var(--s4) var(--s6);font-size:1.05rem}
.btn-compact{padding:var(--s2) var(--s4);min-height:38px;font-size:.9rem}
.section-title{font-family:var(--display);font-size:var(--t-title);margin:var(--s6) 0 var(--s3)}

/* sticky header: the CTA follows once the hero's own has gone */
header.site{justify-content:space-between;position:sticky;top:0;z-index:20;
  background:var(--ivory);transition:box-shadow .15s ease}
header.site .btn-compact{opacity:0;pointer-events:none;transition:opacity .15s ease}
header.site.is-stuck{box-shadow:0 1px 0 var(--line)}
/* Homepage only: clear at the top of the page, then a distinct surface once it
   sticks — deliberately the page ivory, not the hero's deepened ivory, so the
   header reads as a layer above the stage rather than part of it.
   Held just under full opacity so the blur behind it is actually visible. */
header.site--float{background:transparent;border-bottom:1px solid transparent;
  transition:background-color .15s ease,box-shadow .15s ease,border-color .15s ease}
header.site--float.is-stuck{background:rgba(250,246,238,.9);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  border-bottom-color:var(--line);box-shadow:0 2px 10px rgba(19,32,25,.06)}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  header.site--float.is-stuck{background:var(--ivory)}
}
header.site.is-stuck .btn-compact{opacity:1;pointer-events:auto}

/* ---- REAL layer ---------------------------------------------------------- */
.feature-card{background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  padding:var(--s4);margin-top:var(--s5);box-shadow:var(--shadow)}
.feature-head{display:flex;justify-content:space-between;align-items:center;
  margin-bottom:var(--s3)}
.feature-img{display:block;width:100%;max-height:190px;object-fit:cover;
  border-radius:var(--r-input);margin-bottom:var(--s3);background:var(--line)}
.feature-title{font-size:var(--t-heading);margin-bottom:var(--s2)}
.feature-price{font-family:var(--display);font-size:2rem;color:var(--baize);
  font-variant-numeric:tabular-nums;line-height:1.1;margin-bottom:var(--s2)}
.feature-price small{font-size:.85rem;color:var(--muted);font-family:var(--body);
  font-variant-numeric:normal}
.feature-meta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2);
  color:var(--muted);font-size:var(--t-caption);margin-bottom:var(--s4)}
.feature-meta .count{font-family:var(--display);font-variant-numeric:tabular-nums}
.dot{opacity:.5}

.showcase-row{display:grid;grid-template-columns:1fr;gap:var(--s3)}
.show-card{display:block;background:#fff;border:1px solid var(--line);
  border-radius:var(--r-card);padding:var(--s4);text-decoration:none;color:inherit;
  box-shadow:var(--shadow)}
.show-head{display:block;margin-bottom:var(--s2)}
.show-img{display:block;width:100%;height:104px;object-fit:cover;
  border-radius:var(--r-input);margin-bottom:var(--s2);background:var(--line)}
.show-title{display:block;font-family:var(--display);font-weight:600;font-size:.95rem;
  line-height:1.3;margin-bottom:var(--s1)}
.show-price{display:block;font-family:var(--display);font-size:1.15rem;color:var(--baize);
  font-variant-numeric:tabular-nums}
.show-price small{font-size:.75rem;color:var(--muted);font-family:var(--body)}
.show-meta{display:flex;flex-wrap:wrap;gap:var(--s2);color:var(--muted);
  font-size:var(--t-caption);margin-top:var(--s1)}
@media (prefers-reduced-motion:no-preference){
  .show-card{transition:border-color .15s ease,transform .15s ease}
  .show-card:hover{border-color:var(--baize);transform:translateY(-2px)}
}

/* skeleton while the real card loads — never a fake card, just a shape */
.is-skeleton{min-height:220px}
.sk{background:var(--line);border-radius:var(--r-input);opacity:.55}
.sk-pill{width:64px;height:22px;border-radius:var(--r-pill);margin-bottom:var(--s3)}
.sk-img{height:120px;margin-bottom:var(--s3)}
.sk-line{height:14px;margin-bottom:var(--s2)}
.sk-short{width:45%}
@media (prefers-reduced-motion:no-preference){
  .sk{animation:skpulse 1.4s ease-in-out infinite}
  @keyframes skpulse{0%,100%{opacity:.45}50%{opacity:.7}}
}

/* ==========================================================================
   CARD SYSTEM v2 — one component, three variants, ported from
   design/bidpage-card-alternatives.html. Values follow that reference; only the
   colours and radii are swapped for tokens.
     --marquee  (C) hero: full-bleed image, price chip breaking the frame
     --ledger   (B) showcase: header bar, label/value rows, mini stepper
     --example  (B muted) illustrative: ivory, dashed EXAMPLE pill, ghost CTA
   Vivid = real data. Muted = mockup. Never mix the two.
   ========================================================================== */
.bp-pill{display:inline-block;border-radius:var(--r-pill);padding:2px 10px;
  font-family:var(--display);font-weight:600;font-size:.68rem;white-space:nowrap}
.bp-pill--live{background:var(--baize);color:var(--ivory)}
.bp-pill--sold{background:var(--gold);color:var(--ink)}
.bp-pill--example{background:transparent;color:var(--muted);border:1px dashed var(--muted)}
.bp-meta{display:block;font-size:.74rem;color:var(--muted);line-height:1.4}
.bp-btn{display:block;text-align:center;border-radius:9px;padding:9px;
  font-family:var(--display);font-weight:600;font-size:.85rem;text-decoration:none;
  margin-top:10px;background:var(--baize);color:var(--ivory);
  min-height:44px;display:flex;align-items:center;justify-content:center}
.bp-btn--gold{background:var(--gold);color:var(--ink)}
.bp-btn--ghost{background:transparent;border:1px solid var(--line);color:var(--muted)}
/* Hero card CTA. Secondary by design: "Create my auction" is the only gold
   button above the fold, so this must not compete with it. */
.bp-btn--outline{background:transparent;border:1px solid var(--baize);color:var(--baize)}
.bp-imgfill{background:linear-gradient(120deg,#d8e4de,#c7d8d0 60%,#e9e2d2)}

/* ---- image frame ---------------------------------------------------------
   Sellers upload anything — screenshots, phone photos, wide banners. One fixed
   16:9 frame everywhere, filled by two layers of the same image: a blurred,
   over-scaled cover behind, and the real image contained in front. Nothing is
   stretched, nothing is hard-cropped, and every card is the same height.
   The inset shadow keeps the contained edges reading as deliberate. */
.bp-frame{position:relative;display:block;width:100%;aspect-ratio:16/9;
  overflow:hidden;background:var(--line)}
.bp-frame__blur,.bp-frame__img{position:absolute;inset:0;width:100%;height:100%;display:block}
.bp-frame__blur{object-fit:cover;filter:blur(20px) saturate(1.1);transform:scale(1.15);
  /* purely decorative: the sharp layer in front carries the meaning */
}
.bp-frame__img{object-fit:contain;position:relative}
.bp-frame::after{content:'';position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(19,32,25,.06), inset 0 2px 12px rgba(19,32,25,.10)}
/* no image: the frame still holds its shape so heights stay uniform */
.bp-frame--empty{background:linear-gradient(120deg,#d8e4de,#c7d8d0 60%,#e9e2d2)}

/* ---- C · Marquee --------------------------------------------------------- */
.bp-card--marquee{position:relative;display:block;border-radius:16px;overflow:hidden;
  background:#fff;box-shadow:0 6px 18px rgba(19,32,25,.10);
  text-decoration:none;color:inherit;cursor:pointer}
/* Same grammar as the ledger cards: the whole card is the link, and it says so
   on hover. The live dot keeps its own pulse. */
@media (prefers-reduced-motion:no-preference){
  .bp-card--marquee{transition:transform .15s ease,box-shadow .15s ease}
  .bp-card--marquee:hover,.bp-card--marquee:focus-visible{transform:translateY(-2px)}
}
.bp-card--marquee:hover,.bp-card--marquee:focus-visible{
  box-shadow:0 12px 26px rgba(19,32,25,.16)}
.bp-mq-imgwrap{display:block;position:relative;font-size:0}

.bp-mq-chip{position:absolute;right:10px;bottom:-14px;background:var(--gold);color:var(--ink);
  border-radius:12px;padding:6px 12px;font-family:var(--display);font-weight:700;
  font-size:1.05rem;line-height:1.2;box-shadow:0 3px 8px rgba(19,32,25,.2);
  font-variant-numeric:tabular-nums}
.bp-mq-chip--sold{background:var(--baize);color:var(--ivory)}
.bp-card--marquee .bp-bd{display:block;padding:20px 14px 12px}
.bp-mq-title{font-family:var(--display);font-weight:600;font-size:.98rem;line-height:1.3}
.bp-strip{display:flex;flex-wrap:wrap;gap:10px;margin-top:8px;font-size:.72rem;color:var(--muted)}
.bp-live-dot{width:8px;height:8px;border-radius:50%;background:var(--coral);
  display:inline-block;margin-right:4px;vertical-align:middle}
@media (prefers-reduced-motion:no-preference){
  .bp-live-dot{animation:bp-pulse 1.4s infinite}
  @keyframes bp-pulse{50%{opacity:.35}}
}

/* ---- B · Ledger ---------------------------------------------------------- */
.bp-card--ledger{display:block;background:#fff;border:1px solid var(--line);
  border-radius:var(--r-card);overflow:hidden;text-decoration:none;color:inherit}
.bp-hd{display:flex;justify-content:space-between;align-items:center;gap:var(--s2);
  padding:10px 14px;background:var(--ivory);border-bottom:1px solid var(--line)}
.bp-hd b{font-family:var(--display);font-weight:600;font-size:.8rem;letter-spacing:.02em}
.bp-card--ledger .bp-bd{display:block;padding:12px 14px}
.bp-card--ledger .bp-frame{border-radius:9px}
.bp-lg-title{font-family:var(--display);font-weight:600;font-size:.95rem;
  line-height:1.3;margin:8px 0 10px}
.bp-kv{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s3);
  padding:5px 0;border-top:1px solid var(--line);font-size:.78rem}
.bp-kv:first-of-type{border-top:0}
.bp-kv > span{color:var(--muted)}
.bp-kv b{font-family:var(--display);font-variant-numeric:tabular-nums;text-align:right}
.bp-big{font-size:1.35rem;color:var(--baize)}
.bp-mini{display:flex;gap:4px;margin:10px 0 2px}
.bp-dot{width:9px;height:9px;border-radius:50%;background:var(--baize);flex:0 0 auto}
.bp-dot--off{background:transparent;border:1.5px solid var(--line)}
.bp-dot--now{background:transparent;border:2px solid var(--gold)}
@media (prefers-reduced-motion:no-preference){
  .bp-card--ledger{transition:border-color .15s ease,transform .15s ease}
  .bp-card--ledger:hover{border-color:var(--baize);transform:translateY(-2px)}
}

/* ---- B muted · Example --------------------------------------------------- */
.bp-card--example{background:var(--ivory)}
.bp-card--example .bp-kv b{color:var(--ink)}
.bp-card--example .bp-from{color:var(--muted)}
.bp-card--example:hover{border-color:var(--baize)}

/* hero keeps the reference's card proportions rather than stretching the image */
.hero-featured{position:relative;max-width:400px;margin-top:var(--s5)}
#heroCard.is-skeleton{max-width:400px;margin-top:var(--s5)}
/* Solid ground, not a tint: this sits over whatever image the seller uploaded. */
.hero-featured__label{position:absolute;top:10px;left:10px;z-index:2;
  font-family:var(--display);font-weight:700;font-size:.62rem;letter-spacing:.1em;
  color:var(--baize);background:var(--ivory);border-radius:var(--r-pill);
  padding:5px 10px;box-shadow:0 2px 6px rgba(19,32,25,.18)}

@media (min-width:900px){
  /* Top-aligned, not centred: centring left ~54px of dead space above the eyebrow
     whenever the card ran taller than the copy. The card is nudged down so the
     eyebrow's baseline — not its box top — sits level with the card's top edge. */
  .hero-inner{display:grid;grid-template-columns:minmax(0,55fr) minmax(0,45fr);
    gap:var(--s6);align-items:start}
  .hero-inner.is-solo{grid-template-columns:minmax(0,1fr)}
  .hero-featured,#heroCard.is-skeleton{margin-top:14px;justify-self:end;width:100%}
}

/* ---- proof --------------------------------------------------------------- */
.proof{border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:var(--s5) 0;margin-top:0}
.proof-chip,.proof-stripe{max-width:680px}
.proof-chip{display:inline-flex;align-items:center;gap:var(--s2);
  background:rgba(31,122,77,.08);border:1px solid rgba(31,122,77,.22);
  border-radius:var(--r-pill);padding:var(--s2) var(--s4);
  color:var(--ink);text-decoration:none;font-size:.9rem;line-height:1.35}
.proof-chip b{font-weight:600}
.proof-chip__tick{color:var(--ok);font-weight:700;flex:0 0 auto}
.proof-chip:hover{border-color:var(--ok);background:rgba(31,122,77,.12)}
/* Two receipts side by side on a wide screen, stacked on a phone. Deliberately a
   plain wrapping row and not a grid: there are two chips and there will not be a
   third — a row of trophies stops reading as evidence. */
/* The ROW is allowed the full grid so the two chips sit side by side. On desktop it
   does NOT wrap: a wrapping flex line moves an item to the next row rather than
   shrinking it, which stacked the two receipts even with room to spare. With nowrap
   the sale chip shrinks and its title wraps inside the chip instead, so the strip
   stays one row whatever the auction is called. It wraps again on a phone. */
.proof-chips{display:flex;flex-wrap:wrap;gap:var(--s3);align-items:stretch}
@media (min-width:700px){
  .proof-chips{flex-wrap:nowrap}
  .proof-chips .proof-chip{min-width:0}
}
.proof-chips .proof-chip{margin:0}
/* The award chip is the same recipe in gold, so the strip reads as one calm row. */
.proof-chip--award{background:var(--gold-tint);border-color:rgba(232,166,58,.45)}
.proof-chip--award .proof-chip__tick{color:inherit}
.proof-chip--award:hover{border-color:var(--gold);background:rgba(232,166,58,.22)}
.proof-stripe{color:var(--muted);font-size:var(--t-caption);margin-top:var(--s2)}
.proof-stripe strong{color:var(--ink)}
.testimonials{padding-bottom:var(--s2)}
.section-title--center{text-align:center}
/* Three across on the 1000 grid, stacked on a phone. */
.quotes{display:grid;gap:var(--s3);margin-top:var(--s4);grid-template-columns:1fr}
@media (min-width:640px){.quotes{grid-template-columns:repeat(3,1fr)}}
/* Quote CHIPS, not blockquotes. Launch-day comments are a nice-to-have, not the
   receipt, so they get one compact row and stop competing with the proof strip. They
   come out entirely the moment a real buyer or seller says something. */
.quote{margin:0;padding:var(--s3) var(--s4);background:var(--ivory);
  border:1px solid var(--line);border-radius:var(--r-card);border-left:2px solid var(--line)}
.quote p{font-size:.86rem;line-height:1.45}
.quote cite{display:block;font-style:normal;color:var(--muted);
  font-size:.72rem;margin-top:var(--s1)}
.testimonials .section-title{font-size:1.05rem;color:var(--muted);font-weight:600}

/* ---- ILLUSTRATIVE layer -------------------------------------------------- */
.examples{display:grid;grid-template-columns:1fr;gap:var(--s3)}
.example-card{position:relative;display:block;background:var(--ivory);
  border:1px dashed var(--line);border-radius:var(--r-card);padding:var(--s4);
  text-decoration:none;color:inherit}
.example-chip{position:absolute;top:var(--s3);right:var(--s3);
  background:var(--line);color:var(--muted);border-radius:var(--r-pill);
  padding:2px var(--s2);font-size:.68rem;font-family:var(--display);font-weight:600;
  letter-spacing:.04em;text-transform:uppercase}
.example-title{display:block;font-family:var(--display);font-weight:600;font-size:.95rem;
  line-height:1.35;padding-right:72px}
.example-meta{display:block;color:var(--muted);font-size:var(--t-caption);
  margin-top:var(--s1)}
.example-card:hover{border-color:var(--baize);border-style:solid}

/* ---- commit -------------------------------------------------------------- */
.commit{text-align:center;padding:var(--s6) 0 var(--s5);margin-top:var(--s6);
  border-top:1px solid var(--line)}
.commit h2{font-size:var(--t-title);margin-bottom:var(--s4)}

@media (min-width:700px){
  .showcase-row{grid-template-columns:repeat(2,1fr)}
  .examples{grid-template-columns:repeat(2,1fr)}
  /* Three-up from here: these carry no image, so they fit sooner than the card
     grids, and a wide screen should never show them as a full-width stack.
     Scoped to the homepage so the radio cards on /new keep their single column. */
  .wrap--wide .format-cards{grid-template-columns:repeat(3,1fr)}
}
/* At the full 1000 the card grids go three-up; two cards stretched that wide read
   worse than three compact ones. Scoped to the homepage's wide wrapper so the
   format cards on /new keep their single column. */
@media (min-width:940px){
  .showcase-row{grid-template-columns:repeat(3,1fr)}
  .examples{grid-template-columns:repeat(3,1fr)}
}

footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:var(--s3) var(--s4);
  padding:var(--s6) var(--s4);color:var(--muted);font-size:var(--t-caption);
  text-align:center;padding-bottom:calc(var(--s6) + env(safe-area-inset-bottom))}
.footer-line{margin:0}
/* Third-party badge: reserve its box so the footer does not jump when the SVG
   arrives from statics.startupbase.io. */
.sb-badge{display:inline-flex;line-height:0;flex:0 0 auto}
.sb-badge img{height:40px;width:auto;display:block}
footer a{color:inherit;text-decoration:underline;text-underline-offset:2px}
footer a:hover{color:var(--baize)}

@media (prefers-reduced-motion:no-preference){
  .btn-gold:hover{transform:translateY(-1px);transition:transform .15s}
}


/* Watch row: email + button side by side where there is room. */
.watch-row{display:flex;flex-wrap:wrap;gap:var(--s2);margin-top:var(--s3)}
.watch-row input{flex:1 1 200px;min-width:0;margin:0}
.watch-row .btn{flex:0 0 auto;margin:0}

/* Truthful bid state: amber while a card is unconfirmed, so it cannot be mistaken for
   the green "your bid is in" line it replaces. */
.bid-pending{color:#8a6100;background:var(--gold-tint);border-radius:var(--r-input);
  font-size:.88rem;line-height:1.4;margin-top:var(--s2);padding:var(--s2) var(--s3)}
.bid-pending:empty{display:none;padding:0;margin:0}

/* Turnstile is interaction-only: the host is collapsed until a challenge appears, and
   .is-live is added just before one does so the layout makes room rather than jumping. */
/* interaction-only still leaves a sized placeholder in the DOM even when it renders no
   challenge, so collapse the host until an iframe actually exists. The node itself has
   to stay — it carries the hidden cf-turnstile-response input. */
.ts-widget{margin:0;height:0;overflow:hidden}
.ts-widget.is-live{height:auto;min-height:70px;margin:var(--s3) 0;overflow:visible}

/* ---- /my ------------------------------------------------------------------ */
.my-head{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;
  gap:var(--s3);margin-bottom:var(--s4)}
.my-empty{text-align:center;padding:var(--s6) var(--s4)}
.my-empty h3{font-size:var(--t-heading);margin-bottom:var(--s2)}
