/* Spare — climbing punch passes going spare at Bangkok gyms.
   Committed to a single light theme for now: the palette is painted explicitly
   so the page holds regardless of the viewer's OS appearance.
   Spare never touches money: a price is information, settled at the gym.
   Palette from src/styles/tokens.css, verified by scripts/check-contrast.mjs. */
:root{
  --bg:#faf6f3; --surface:#ffffff; --sunken:#f5edf3;
  --text:#1c0f2b; --muted:#5d5068; --on-accent:#ffffff;
  --hair:#ece3ea; --dash:#d6c8d6;
  /* Chart hues. Separated by lightness as well as hue, so the pair survives
     colour blindness; both series are labelled in text regardless. */
  --c-in:#3d2456; --c-out:#b83e14;
  /* Plum is the accent: it fills with white on top and still reads as a word.
     Ember is the hot role — the one loud colour, and it only carries ink. */
  --accent:#2b1640; --accent-soft:#f5edf3; --focus:#2b1640;
  --hot:#ff6b3d; --hot-soft:#ffe9e1; --hot-text:#b83e14; --on-hot:#1c0f2b;
  --pink:#ffc2d4; --plum-raised:#3d2456;
  --success:#177453; --warning:#7a4f08;
  /* Red is reserved: a warning, a flag, a report, or something to act on now.
     Crimson rather than scarlet, so it is never mistaken for ember. */
  --danger:#bd1b43; --danger-soft:#fdeaef; --danger-line:#f6c2d0;
  --glass-tint:250 246 243; --glass-alpha:.62;
  --font:'Onest','Geist','Noto Sans Thai','SF Pro Text',system-ui,-apple-system,sans-serif;
  --r-s:12px; --r-m:18px; --r-l:26px; --r-full:9999px;
  --lift:0 1px 2px rgb(28 15 43/.04), 0 8px 24px -12px rgb(28 15 43/.16);
  --ease:cubic-bezier(.32,.72,0,1);
}


/* ---- device frame ----
   The app is authored at phone width, so on a large screen it is presented in a
   handset rather than stretched. On an actual phone the frame is dropped and the
   app runs full-bleed — the frame is packaging, not part of the product. */
/* ---- shell ----
   This was a handset mockup: a bezel, a notch and a painted-on 9:41, with the
   app inside it. That was packaging for something being shown, and it is the
   wrong thing for something being used — the app now has its own address and
   fills whatever it is opened in.

   The three elements survive as plain containers rather than being deleted,
   because the layout below positions against them: `.device` is the block the
   screens are laid out in, and `.vp` scrolls inside it. Collapsing the chain
   into one div would mean rewriting every rule that depends on it for no gain
   the reader would ever see. */
/* No device wrapper any more: the page is the app. *//* The scrolling element is the device, not the window, so the sidebar and the
   bottom bar can stay put while the board moves. */
/* The old phone-frame scroller. The document scrolls now, like a web app:
   iOS collapses its bar, overscroll works, scroll position is the page's. */

*{box-sizing:border-box}
/* manipulation drops the double-tap-zoom gesture (and with it the 300ms tap
   delay that comes from waiting to see if a second tap is coming). Panning and
   scrolling are untouched. */
html{touch-action:manipulation}
body{margin:0;background:var(--bg);color:var(--text);font-family:var(--font);
  letter-spacing:-.011em;-webkit-font-smoothing:antialiased}
/* Thai needs more room between lines than Latin — its vowel and tone marks sit
   above and below the base glyph, and tight leading collides them. */
:root[lang="th"] body{letter-spacing:0}
:root[lang="th"] .mark,:root[lang="th"] h1,:root[lang="th"] h2,
:root[lang="th"] h3{letter-spacing:0;line-height:1.35}
:root[lang="th"] .lede,:root[lang="th"] .sub,:root[lang="th"] .fieldhint,
:root[lang="th"] .note,:root[lang="th"] .obnote{line-height:1.65}
:root[lang="th"] .ds-link,:root[lang="th"] .btn,:root[lang="th"] .seg button,
:root[lang="th"] .chip{line-height:1.4}
/* The content column. Full width on a phone with a real gutter, a readable
   column on anything wider — instead of a 430px frame centred on the page. */
/* One gutter, named, so the rows that bleed to the viewport edge (gym strip,
   filter chips) cancel exactly what the column adds. They used to assume
   20px; the column now pads 16–24px, and the 4px difference was a horizontal
   scrollbar on every phone. */
.shell{--gutter:clamp(16px,4vw,24px);
  inline-size:100%;max-inline-size:34rem;margin-inline:auto;
  padding:0 var(--gutter) calc(92px + env(safe-area-inset-bottom,0px));
  min-block-size:100dvh}
/* Installed to the home screen, the app can sit under a notch or status bar;
   the inset is 0 in a normal browser tab, so this costs nothing there. */
.shell{padding-top:env(safe-area-inset-top,0px)}
:where(a,button,input,select,textarea,[tabindex]):focus-visible{outline:2px solid var(--focus);
  outline-offset:3px;border-radius:var(--r-s)}
@media (prefers-reduced-motion:reduce){*{transition-duration:.01ms!important}}
h1,h2,h3{margin:0;font-weight:600;letter-spacing:-.028em}
.screen{display:none}.screen.on{display:block}

/* ---- logo ----
   Outlined so it sits on any ground and inherits the text colour; the mark is
   two linked passes with a hand-off arrow through them. */
.logomark{inline-size:1em;block-size:1em;flex:none}
/* The mark's two strokes, named once. Anything standing on plum flips the back
   stroke to pink, where plum on plum would vanish. */
:root{--mark-front:var(--hot);--mark-back:var(--accent)}
.on-plum{--mark-back:var(--pink)}
.brandrow{display:flex;align-items:center;gap:10px}
.brandrow .logomark{font-size:1.875rem}
.authbrand{display:flex;align-items:center;gap:14px}
.authbrand .logomark{font-size:3.25rem}

/* ---- header ---- */
/* ---- the board's head ----
   A plum band carrying the brand, the account controls and the search, with
   the board itself on paper below it. It bleeds to the viewport edges by
   cancelling exactly what the column adds (see --gutter on .shell). */
.feedhead{background:var(--accent);color:#fff;
  margin:calc(-1 * env(safe-area-inset-top,0px)) calc(-1 * var(--gutter)) 18px;
  padding:env(safe-area-inset-top,0px) var(--gutter) 18px}
.feedhead .lede,.feedhead .count{color:#e4d8ec}
.feedhead .gbtn{background:var(--plum-raised);color:#fff}
.feedhead .signin-pill{background:var(--hot);color:var(--on-hot)}
.top{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:18px 0 6px}
.top > div:first-child{min-width:0}
.top-r{display:flex;align-items:center;gap:8px;flex:none}
.gbtn{inline-size:34px;block-size:34px;display:grid;place-items:center;border:0;cursor:pointer;
  border-radius:var(--r-full);background:var(--sunken);color:var(--text)}
.mark{font-size:1.625rem;font-weight:600;letter-spacing:-.04em}
/* "Spare" beside the mark is the lockup, not a page title, so it is set in the
   brand's own face rather than the interface one. */
.brandrow .mark,.auth-mark{font-family:'Space Grotesk',var(--font);font-weight:700;letter-spacing:-.045em}
.lede{margin:4px 0 0;color:var(--muted);font:400 .875rem/1.4 var(--font)}
.back{position:relative;display:inline-flex;align-items:center;gap:7px;border:0;
  background:none;padding:0;cursor:pointer;
  color:var(--muted);font:500 .875rem/1 var(--font);margin:18px 0 14px}
/* The label is 15px tall, so the button was a 15px target. Extend the hit area
   to 44pt with a pseudo-element rather than padding, which would move every
   back button on every screen. */
.back::before{content:"";position:absolute;left:0;right:0;
  top:50%;height:44px;transform:translateY(-50%)}

/* ---- bell ---- */
.bell{position:relative}
/* The dot sits on the glyph, not the button box, so it reads as attached to the
   bell rather than floating in the corner. */
.bell .dot{position:absolute;top:2px;right:0;min-inline-size:17px;block-size:17px;padding:0 4px;
  border-radius:var(--r-full);background:var(--danger);color:var(--on-accent);
  box-shadow:0 0 0 2px var(--bg);font:600 .625rem/17px var(--font);text-align:center;
  font-variant-numeric:tabular-nums}
.bell[data-unread="0"] .dot{display:none}

/* ---- notifications ---- */
.alerts{margin-top:4px}
.alert{display:flex;gap:12px;align-items:flex-start;width:100%;text-align:left;border:0;
  background:none;font:inherit;color:inherit;cursor:pointer;padding:16px 0;
  border-top:1px solid var(--hair)}
.alert:first-child{border-top:0}
.alert .ico{inline-size:34px;block-size:34px;border-radius:var(--r-full);flex:none;
  display:grid;place-items:center;background:var(--sunken);color:var(--muted)}
.alert .face{inline-size:34px;block-size:34px;font-size:.6875rem}
.alert-t{flex:1;min-width:0}
.alert-t p{margin:0;font:400 .875rem/1.4 var(--font)}
.alert-t p b{font-weight:600}
.alert-t .w{margin-top:6px;color:var(--muted);font:400 .75rem/1 var(--font)}
/* Unread is carried by a mark, not by colour alone. */
.alert .new{inline-size:7px;block-size:7px;border-radius:var(--r-full);background:var(--accent);
  flex:none;margin-top:8px}
.alert[data-new="0"] .new{background:none}
.alerts-wrap{background:var(--surface);border-radius:var(--r-l);padding:4px 18px;
  box-shadow:var(--lift);margin-top:14px}

/* ---- side switch ----
   Spare has two sides: people with a pass spare, and people who want one.
   The switch names them as what you're looking at, not as a role you "are". */
/* Take or Give: the two sides of the board, above the list where the old
   grid/list toggle used to be. Compact, because it sits beside the count. */
.seg{display:flex;gap:2px;padding:3px;margin:0;flex:none;
  background:var(--sunken);border-radius:var(--r-full)}
/* flex-basis holds each half at a readable width and shrinking is off, so
   when the two labels can no longer share a line the pair wraps instead of
   squeezing two sentences into one row. */
.seg button{flex:none;min-width:0;display:inline-flex;align-items:center;justify-content:center;gap:6px;
  border:0;cursor:pointer;background:none;color:var(--muted);white-space:nowrap;
  border-radius:var(--r-full);padding:9px 16px;font:600 .8125rem/1 var(--font);
  transition:background .2s var(--ease),color .2s var(--ease)}
.seg button svg{flex:none;opacity:.85}
.seg button[aria-pressed="true"] svg{opacity:1}
.seg button[aria-pressed="true"]{background:var(--surface);color:var(--text);
  box-shadow:0 1px 2px rgb(28 15 43/.06)}

/* ---- request card (someone looking) ---- */
.req .logo{background:var(--sunken);color:var(--muted)}
.want{margin-top:16px;display:flex;align-items:baseline;gap:8px}
.want b{font:600 1.0625rem/1 var(--font);letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.want span{color:var(--muted);font:400 .8125rem/1 var(--font)}
.havebtn{margin-left:auto;background:var(--accent);color:var(--on-accent);border:0;cursor:pointer;
  border-radius:var(--r-full);padding:10px 16px;font:500 .8125rem/1 var(--font)}

/* Marks the first gym picked. It is a label, not decoration: the order of the
   list decides which gym the board sorts by, and nothing else on screen says
   so. */
.homeflag{display:inline-block;margin-inline-start:7px;border-radius:var(--r-full);
  padding:2px 8px;background:var(--accent-soft);color:var(--accent);
  font:600 .625rem/1.5 var(--font);font-style:normal;vertical-align:middle}

/* Deliberately quiet: it qualifies the claim beside it rather than competing
   with it. Not red — nothing is wrong, the number is simply unconfirmed. */
.unconfirmed{display:inline-block;margin-inline-start:4px;padding:1px 6px;
  border-radius:var(--r-full);background:var(--sunken);color:var(--muted);
  font:600 .5625rem/1.5 var(--font);vertical-align:middle;white-space:nowrap;cursor:help}

/* Sits above the bottom nav, inside the app rather than over the whole page,
   and is announced to a screen reader as a status rather than an alert. */
.toast{position:fixed;left:50%;transform:translate(-50%,14px);
  bottom:calc(104px + env(safe-area-inset-bottom,0px));z-index:75;
  max-inline-size:min(20rem,calc(100% - 40px));
  background:var(--text);color:var(--bg);border-radius:var(--r-m);
  padding:12px 16px;font:500 .8125rem/1.4 var(--font);
  box-shadow:0 12px 30px -12px rgb(28 15 43/.5);
  opacity:0;pointer-events:none;transition:opacity .2s var(--ease),transform .25s var(--ease)}
.toast.on{opacity:1;transform:translate(-50%,0)}
.toast b{font-weight:700}
@media (prefers-reduced-motion:reduce){.toast{transition-duration:.01ms}}

.mybid{margin-top:12px;background:var(--accent-soft);border-radius:var(--r-m);padding:12px 14px}
.mybid-line{margin:0;color:var(--accent);font:500 .8125rem/1.45 var(--font)}
.mybid .handover{margin-top:10px}

.reqbanner{margin-top:14px;background:var(--accent-soft);border-radius:var(--r-l);padding:14px 16px}
.reqbanner-l{margin:0;color:var(--accent);font:500 .9375rem/1.4 var(--font)}
.reqbanner-l b{font-weight:700}
.reqbanner-n{margin:6px 0 0;color:var(--text);font:400 .875rem/1.45 var(--font)}
.replyrow{display:flex;align-items:center;gap:10px;width:100%;text-align:left;border:0;cursor:pointer;
  background:var(--surface);border-radius:var(--r-m);padding:10px 12px;margin-top:6px;font:inherit;color:inherit}
.replyrow span{flex:1;font:600 .875rem/1 var(--font)}
.replyrow em{font-style:normal;color:var(--accent);font:600 .8125rem/1 var(--font)}
.card.req{cursor:pointer}

.fieldhint{margin:10px 2px 0;color:var(--muted);font:400 .75rem/1.45 var(--font);
  text-wrap:pretty}

/* ---- touch targets ----
   Apple's HIG asks for 44×44pt of hittable area. Several controls here are
   deliberately smaller than that visually — an icon button, a filter chip, a
   text link — so the target is extended with a pseudo-element instead of
   inflating the design. The pixels you see stay the same; the pixels that
   respond grow. */
.gbtn,.eye,.chip,.acc,.dec,.havebtn,.pipbtn,.morelink,.linkish,
.back,.forgot,.mrow.edit,.setbtn,.sheet-x,.skip,.ds-toggle,.ds-bell,
.stepper button,#offersug button,.picksug button,.avatar-actions button,
.langswitch button,.auth-alt button,.pickacts button,.sf-col button,
.histfilter button,.switch button,.opt2 button{
  position:relative;
}
.gbtn::after,.eye::after,.chip::after,.acc::after,.dec::after,
.havebtn::after,.pipbtn::after,.morelink::after,.linkish::after,.back::after,
.forgot::after,.mrow.edit::after,.setbtn::after,.sheet-x::after,.skip::after,
.ds-toggle::after,.ds-bell::after,.stepper button::after,#offersug button::after,
.picksug button::after,.avatar-actions button::after,.langswitch button::after,
.auth-alt button::after,.pickacts button::after,.sf-col button::after,
.histfilter button::after,.switch button::after,.opt2 button::after{
  content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  inline-size:max(100%,44px);block-size:max(100%,44px);
}
/* A checkbox and a switch are <input>s, which cannot carry a pseudo-element at
   all. Both already sit inside a <label>, and clicking anywhere on that label
   toggles them — so the real target is the whole row, which is well over 44px.
   A couple of others are worth growing for real rather than faking: a filter
   chip and a row of accept/decline buttons read as cramped at 31px. */
label.item,label.consent{min-block-size:44px}
/* The one exception: `terms` and `privacy notice` are links inside a sentence.
   A 44px target there would overlap the lines above and below, which is worse
   than a small one — the whole consent row is already tappable. */
.chip{padding:10px 14px}
.acc,.dec{padding:12px 16px}
.seg button{min-block-size:40px}
.tab{min-block-size:46px}

.d-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
.d-share{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--hair);
  background:var(--surface);color:var(--text);cursor:pointer;border-radius:var(--r-full);
  padding:10px 16px;font:500 .8125rem/1 var(--font);position:relative}
.d-share::after{content:"";position:absolute;left:50%;top:50%;
  transform:translate(-50%,-50%);inline-size:max(100%,44px);block-size:max(100%,44px)}
.d-share:hover{border-color:var(--border-input);color:var(--accent)}
.d-save[aria-pressed="true"]{background:var(--accent-soft);border-color:var(--accent-soft);
  color:var(--accent)}
.d-save[aria-pressed="true"] svg{fill:currentColor}
.d-report:hover{color:var(--danger);border-color:var(--danger)}


/* ---- card actions ----
   Save and share sit on the card so a pass can be kept or passed along without
   opening it. They are spans with a button role because the card itself is a
   button and nesting one inside another is invalid. The 44pt target comes from
   a pseudo-element so the row stays visually light. */
.cardacts{display:flex;gap:8px;margin-top:12px;padding-top:12px;
  border-top:1px solid var(--hair)}
.cardact{position:relative;display:inline-flex;align-items:center;gap:6px;
  padding:7px 12px;border-radius:var(--r-full);background:var(--sunken);
  color:var(--muted);font:600 .75rem/1 var(--font);cursor:pointer;
  -webkit-tap-highlight-color:transparent;transition:background .15s var(--ease),color .15s var(--ease)}
.cardact::before{content:"";position:absolute;inset-inline:0;top:50%;
  block-size:44px;transform:translateY(-50%)}
.cardact:hover{background:var(--hair);color:var(--text)}
.cardact.on{background:var(--accent-soft);color:var(--accent)}
.cardact:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.cardact svg{flex:none}



/* How much of a set has gone. Muted when nothing has moved, accented once it
   starts, because a set that is going is a reason to decide today. */
.stat .gone{display:block;font:500 .6562rem/1.3 var(--font);color:var(--muted);margin-top:3px}
.stat .gone.moving{color:var(--accent);font-weight:600}
.stat .v.free{color:var(--accent)}




/* Ask-a-price or give-it-away. A segmented pair rather than a checkbox, because
   both are ordinary choices and a checkbox would make one of them the default
   and the other an exception. */
.segrow{display:flex;gap:6px;margin-top:14px}
.segbtn{flex:1;min-height:44px;border:1px solid var(--hair);background:var(--surface);
  border-radius:var(--r-m);padding:11px 12px;cursor:pointer;
  font:600 .8125rem/1.2 var(--font);color:var(--muted)}
.segbtn.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.segbtn:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.freehint{margin:10px 2px 0;color:var(--accent);font:500 .75rem/1.45 var(--font)}
/* A price box reading 0 is saying "free", so it says it in the accent rather
   than looking like a field somebody forgot to fill in. */
#f-price.isfree{color:var(--accent);font-weight:600}


/* The gym's mark beside its name on the listing. Bigger than the card's,
   because here it is identifying the whole screen rather than one row. */
.d-head{display:flex;align-items:center;gap:12px;margin-top:2px}
.d-head .mark{margin:0;min-width:0;overflow-wrap:anywhere}
.d-mark{flex:none}
.d-mark .logo{inline-size:46px;block-size:46px;border-radius:14px;font-size:.9375rem}
.d-mark .logo.brand{background:var(--surface);box-shadow:0 0 0 1px var(--hair)}
.d-mark .logo img{inline-size:100%;block-size:100%;object-fit:contain;padding:6px}
@media (max-width:360px){.d-mark .logo{inline-size:40px;block-size:40px}}



/* The currency setting is a row plus two things under it, not four things in a
   row. `.item` is display:flex, so its children were laid out side by side and
   the explanatory note refused to wrap — which pushed the settings screen
   sideways by 91px. Give this one item its own two-column grid: icon beside
   the label, everything else on its own full-width line beneath. */
#fxsetting{display:grid;grid-template-columns:auto 1fr;gap:6px 12px;align-items:center}
#fxsetting .k{min-width:0}
#fxsetting .fxrow,#fxsetting .fxnote{grid-column:1/-1;min-width:0}

/* The converted price. Deliberately quieter than the baht figure beside it:
   this is orientation, not a sum anybody pays. */
.fx{display:block;margin-top:3px;font:500 .6562rem/1.3 var(--font);color:var(--muted);
  font-variant-numeric:tabular-nums}
.stat .fx{margin-top:2px}
.fxnote{margin:10px 0 0;padding:9px 11px;border-radius:var(--r-s);
  background:var(--sunken);color:var(--muted);font:400 .6875rem/1.5 var(--font)}
.fxnote b{color:var(--text);font-weight:600}
.fxrow{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:10px}
.fxrow select{flex:1;min-inline-size:150px;min-block-size:44px;
  border:1px solid var(--hair);border-radius:var(--r-m);background:var(--surface);
  padding:10px 12px;font:500 .8125rem/1 var(--font);color:var(--text)}
.fxstamp{font:500 .6875rem/1.4 var(--font);color:var(--muted)}
.fxstamp .dot{display:inline-block;inline-size:7px;block-size:7px;border-radius:50%;
  background:var(--muted);margin-inline-end:5px;vertical-align:middle}
.fxstamp.live .dot{background:var(--success)}


/* ---- the seller box ----
   The rating sits top right, where a reader looking for it will look. Every
   figure in here is paired with the thing that makes it readable: a score with
   its count, a rate with its denominator. A number on its own would be an
   assertion rather than evidence. */
.seller{display:grid;grid-template-columns:auto 1fr auto;gap:12px;
  align-items:start;margin-top:14px;padding:14px;border-radius:var(--r-l);
  background:var(--surface);box-shadow:0 0 0 1px var(--hair)}
.seller-face{flex:none}
.seller-face .face{inline-size:46px;block-size:46px;font-size:1rem}
.seller-who{min-width:0;padding-top:2px}
.seller-who .who-link{display:block;font:600 .9375rem/1.2 var(--font);color:var(--text);cursor:pointer}
.seller-who .who-link:hover{text-decoration:underline}
.seller-meta{display:block;margin-top:4px;color:var(--muted);font:400 .75rem/1.4 var(--font)}

.seller-rate{text-align:right;flex:none}
.stars{display:flex;gap:1px;justify-content:flex-end;color:var(--warning)}
.star{display:block;line-height:0}
.star.none{color:var(--dash)}
.rate-n{display:block;margin-top:4px;font:700 .8125rem/1 var(--font);color:var(--text);
  font-variant-numeric:tabular-nums}
.rate-n small{font:500 .6875rem/1 var(--font);color:var(--muted);margin-inline-start:4px}
.rate-none{font:500 .6875rem/1.4 var(--font);color:var(--muted);text-align:right;max-inline-size:96px}

.seller-stats{grid-column:1/-1;display:grid;grid-template-columns:repeat(2,1fr);
  gap:7px;margin-top:2px}
.seller-stat{display:flex;align-items:baseline;gap:7px;background:var(--sunken);
  border-radius:var(--r-m);padding:9px 11px;min-width:0}
.seller-stat b{font:700 .875rem/1.15 var(--font);color:var(--text);
  font-variant-numeric:tabular-nums;flex:none}
.seller-stat span{color:var(--muted);font:500 .6875rem/1.3 var(--font);min-width:0}

.seller-verif{grid-column:1/-1;display:flex;gap:6px;flex-wrap:wrap}
.vchip{display:inline-flex;align-items:center;gap:5px;border-radius:var(--r-full);
  padding:4px 9px;font:600 .6562rem/1.4 var(--font);background:var(--accent-soft);color:var(--accent)}
.vchip.off{background:var(--sunken);color:var(--muted)}

.seller-foot{grid-column:1/-1;display:flex;align-items:center;gap:12px;
  justify-content:space-between;flex-wrap:wrap}
.seller-note{margin:0;color:var(--muted);font:400 .7188rem/1.5 var(--font);flex:1;min-inline-size:180px}
/* The one thing a reader can actually do from this box when there are no
   numbers in it, so it stops looking like a tertiary link. */
.seller-go{min-block-size:38px;padding:9px 16px;border-radius:var(--r-full);
  border:1px solid var(--accent);background:var(--accent);cursor:pointer;
  font:600 .7812rem/1 var(--font);color:var(--on-accent);flex:none;position:relative}
.seller-go::before{content:"";position:absolute;inset-inline:0;top:50%;
  block-size:44px;transform:translateY(-50%)}
.seller-go:hover{filter:brightness(1.08)}
.seller-badge{display:inline-flex;align-items:center;gap:5px;margin-inline-start:6px;
  border-radius:var(--r-full);padding:2px 8px;font:600 .6562rem/1.5 var(--font);
  background:var(--accent-soft);color:var(--accent);vertical-align:middle}
.seller-badge.new{background:var(--sunken);color:var(--muted)}
@media (max-width:370px){
  .seller{grid-template-columns:auto 1fr}
  .seller-rate{grid-column:1/-1;text-align:left}
  .stars{justify-content:flex-start}
  .rate-none{text-align:left;max-inline-size:none}
  .seller-stats{grid-template-columns:1fr}
}


/* A render failure says so, rather than leaving a plausible-looking blank. */
.renderwarn{position:relative;margin:10px 0 0;padding:10px 12px 10px 34px;
  border-radius:var(--r-s);background:var(--surface);color:var(--text);
  box-shadow:0 0 0 1px var(--danger-line);font:500 .75rem/1.45 var(--font)}
.renderwarn::before{content:"!";position:absolute;inset-inline-start:11px;top:10px;
  display:grid;place-items:center;inline-size:15px;block-size:15px;border-radius:50%;
  background:var(--danger);color:var(--on-accent);font:700 .625rem/1 var(--font)}



.attendask{display:flex;gap:11px;align-items:flex-start;margin-top:14px;
  padding:13px 15px;border-radius:var(--r-m);background:var(--surface);
  box-shadow:var(--lift);cursor:pointer;min-block-size:44px}
.attendask input{appearance:none;-webkit-appearance:none;margin:1px 0 0;flex:none;
  inline-size:22px;block-size:22px;border-radius:7px;
  border:1.5px solid var(--border-input);background:var(--surface);
  cursor:pointer;position:relative}
.attendask input:checked{background:var(--accent);border-color:var(--accent)}
.attendask input:checked::after{content:"";position:absolute;left:7px;top:3px;
  inline-size:5px;block-size:10px;border:solid var(--on-accent);
  border-width:0 2px 2px 0;transform:rotate(45deg)}
.attendask input:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.attendask b{display:block;font:600 .8125rem/1.3 var(--font);color:var(--text)}
.attendask small{display:block;margin-top:4px;color:var(--muted);
  font:400 .6875rem/1.5 var(--font)}

/* Owner-present. Not a warning — plenty of gyms work this way and it is a
   normal thing to agree — but it is a condition on the handover, so it reads
   as a condition rather than as a note. */
.setbadge.attend{background:var(--accent-soft);color:var(--accent);gap:6px}
.setbadge.attend svg{flex:none}
.attendline{display:flex;gap:9px;align-items:flex-start;margin:12px 0 0;
  padding:12px 14px;border-radius:var(--r-m);background:var(--accent-soft);
  color:var(--accent);font:400 .75rem/1.5 var(--font)}
.attendline svg{flex:none;margin-top:.15em}
.attendline b{font-weight:600}


/* The backend banner. Only appears when the app is running on local data, and
   says what that actually means for the person reading it. */
.backendbar{position:fixed;inset-inline:0;bottom:0;z-index:90;
  padding:9px 16px;padding-bottom:calc(9px + env(safe-area-inset-bottom,0px));
  text-align:center;font:500 .6875rem/1.4 var(--font)}
.backendbar[hidden]{display:none}
.backendbar[data-tone="warn"]{background:var(--danger-soft);color:var(--danger);
  box-shadow:0 -1px 0 var(--danger-line)}



.bidmsg{display:inline-flex;align-items:center;margin-top:10px;border:1px solid var(--hair);
  background:var(--surface);color:var(--text);cursor:pointer;border-radius:var(--r-full);
  padding:9px 14px;font:600 .75rem/1 var(--font);min-block-size:38px}
.bidmsg:hover{border-color:var(--accent);color:var(--accent)}

/* The hand-off row. Not a warning and not a celebration — a thing two people
   still have to do, stated plainly. */
.handover{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:10px;
  padding:11px 13px;border-radius:var(--r-m);background:var(--accent-soft);
  color:var(--accent);font:400 .75rem/1.45 var(--font)}
.handover button{flex:none;border:0;cursor:pointer;border-radius:var(--r-full);
  padding:9px 14px;font:600 .75rem/1 var(--font);background:var(--accent);
  color:var(--on-accent);min-block-size:38px}
.handover em{font-style:normal;opacity:.75;flex-basis:100%}
.handover.waiting{background:var(--sunken);color:var(--muted)}

/* A free pass says so in the accent, because it is the most interesting thing
   on the card and ฿0 would otherwise read as a missing value. */
.stat .v.free{color:var(--accent)}
.freetag{display:inline-flex;align-items:center;gap:5px;background:var(--accent);
  color:var(--on-accent);border-radius:var(--r-full);padding:3px 9px;
  font:600 .6875rem/1.35 var(--font)}

/* ---- notice ----
   The warning used to be a pink box with a red outline, a red triangle and red
   text: the same box every product uses, and all of it shouting at once. This
   one is a ticket stub, because a pass is what is being exchanged. The red is
   spent on the stub alone, the perforation reads as "tear here" rather than as
   a border, and the words are set in ordinary ink so they are read, not
   skimmed past as decoration. Notches are painted in the page colour, so the
   card looks punched without a mask that would clip its own outline. */
.notice{display:grid;grid-template-columns:auto 1fr;margin:12px 0;
  background:var(--surface);border-radius:var(--r-m);overflow:hidden;
  box-shadow:0 0 0 1px var(--hair),var(--lift)}
.notice-stub{position:relative;display:grid;place-items:center;inline-size:58px;
  color:var(--danger);
  background:
    radial-gradient(circle 8px at 100% 0,var(--bg) 7px,transparent 8px),
    radial-gradient(circle 8px at 100% 100%,var(--bg) 7px,transparent 8px),
    var(--danger-soft)}
.notice-stub::after{content:"";position:absolute;inset-block:14px;inset-inline-end:0;
  border-inline-end:2px dotted var(--danger-line)}
.notice-body{padding:13px 16px 14px 14px;min-inline-size:0;
  background:
    radial-gradient(circle 8px at 0 0,var(--bg) 7px,transparent 8px),
    radial-gradient(circle 8px at 0 100%,var(--bg) 7px,transparent 8px),
    var(--surface)}
.notice-body b{display:block;font:600 .875rem/1.3 var(--font);letter-spacing:-.015em;
  color:var(--text)}
.notice-body p{margin:4px 0 0;color:var(--muted);font:400 .8125rem/1.5 var(--font);
  text-wrap:pretty}
.notice-body button{border:0;background:none;padding:0;cursor:pointer;color:var(--danger);
  font:inherit;font-weight:600;text-decoration:underline;text-underline-offset:2px}
.notice.lg{margin-top:18px}
.notice.lg .notice-stub{inline-size:68px}
.notice.lg .notice-body{padding:16px 18px 18px 16px}
.notice.lg .notice-body b{font-size:1rem}
.notice.lg .notice-body p{font-size:.875rem;line-height:1.55}

/* The same red, at the size of a sentence: what is wrong with one field. It
   says what to change and sits under the field it is about, so it never needs
   a box. */
.problem{display:flex;align-items:flex-start;gap:8px;margin:8px 2px 0;
  color:var(--danger);font:500 .75rem/1.45 var(--font)}
.problem::before{content:"!";flex:none;display:grid;place-items:center;inline-size:15px;
  block-size:15px;border-radius:50%;background:var(--danger);color:var(--on-accent);
  font:700 .625rem/1 var(--font)}
.field.invalid,.offerbox.invalid{box-shadow:0 0 0 1.5px var(--danger),var(--lift)}
.field.invalid>span:first-child{color:var(--danger)}

/* ---- guest ---- */
/* `display:grid` on .gbtn outranks a bare [hidden] rule, so state the override
   explicitly rather than relying on the host stylesheet to win. */
[hidden]{display:none !important}
.signin-pill{display:inline-flex;align-items:center;gap:6px;border:0;cursor:pointer;
  background:var(--accent);color:var(--on-accent);border-radius:var(--r-full);
  padding:10px 14px;font:600 .8125rem/1 var(--font);white-space:nowrap;flex:none}
/* A guest is told what the wall is for before they hit it, not after. */
.guestbar{display:flex;align-items:center;gap:10px;margin-top:14px;background:var(--surface);
  border-radius:var(--r-m);padding:12px 14px;box-shadow:var(--lift);
  color:var(--muted);font:400 .8125rem/1.45 var(--font)}
.guestbar svg{flex:none;color:var(--accent)}
.guestbar button{flex:none;margin-left:auto;border:0;background:none;cursor:pointer;
  color:var(--accent);font:600 .8125rem/1 var(--font);white-space:nowrap}

/* ---- post sheet ---- */
.sheet{position:fixed;inset:0;z-index:60;display:none;align-items:flex-end;justify-content:center;
  background:rgb(28 15 43/.4);padding:20px;padding-bottom:calc(20px + env(safe-area-inset-bottom,0px))}
.sheet.on{display:flex}
.sheet-c{width:100%;max-width:390px;background:var(--surface);border-radius:var(--r-l);padding:20px}
.sheet-c h2{font-size:1.125rem}
.sheet-logo{display:block;margin:0 0 14px}
.as-form{display:grid;gap:10px;margin-top:4px}
.as-form .btn{margin-top:4px}
.as-link{display:block;margin:12px auto 0;border:0;background:none;cursor:pointer;color:var(--muted);
  font:500 .8125rem/1.2 var(--font);text-decoration:underline;text-underline-offset:.2em}
.as-new{margin:14px 0 0!important;text-align:center;color:var(--muted);font:400 .875rem/1.4 var(--font)}
.as-new button{border:0;background:none;cursor:pointer;padding:0;color:var(--accent);font:600 .875rem/1.4 var(--font);
  text-decoration:underline;text-underline-offset:.2em}
.sheet-logo .logomark{display:block;inline-size:44px;block-size:44px}
.sheet-c p{margin:6px 0 16px;color:var(--muted);font:400 .8125rem/1.45 var(--font)}
.opt2{display:grid;gap:9px}
.opt2 button{display:flex;align-items:center;gap:13px;width:100%;text-align:left;border:0;cursor:pointer;
  background:var(--sunken);color:var(--text);border-radius:var(--r-m);padding:16px;font:inherit}
.opt2 .oi{inline-size:36px;block-size:36px;border-radius:var(--r-full);flex:none;display:grid;
  place-items:center;background:var(--accent);color:var(--on-accent)}
.opt2 b{display:block;font:600 .9375rem/1 var(--font)}
.opt2 span{display:block;margin-top:4px;color:var(--muted);font:400 .75rem/1.35 var(--font)}
.sheet-x{display:block;width:100%;margin-top:12px;border:0;background:none;cursor:pointer;
  color:var(--muted);font:500 .875rem/1 var(--font);padding:10px}

/* ---- search ---- */
.search{display:flex;align-items:center;gap:10px;margin-top:14px;background:var(--surface);
  border-radius:var(--r-m);padding:14px 16px}
.search svg{flex:none;color:var(--muted)}
.search input{flex:1;min-width:0;border:0;background:none;color:var(--text);
  font:400 .9375rem/1 var(--font);padding:0}
.search input::placeholder{color:var(--muted)}
.search button{flex:none;border:0;background:none;cursor:pointer;color:var(--muted);
  padding:0;display:none}
.search.has button{display:block}
.count{margin:14px 2px 0;color:var(--muted);font:400 .75rem/1 var(--font)}

/* ---- the prompt ----
   Ember, because it is the one thing on the board asking for something rather
   than offering it. Ink on ember, never white. */
.promo{display:flex;align-items:center;gap:14px;margin:4px 0 18px;padding:16px 18px;
  border-radius:var(--r-m);background:var(--hot);color:var(--on-hot)}
.promo b{display:block;font:600 1.0625rem/1.25 var(--font);letter-spacing:-.015em}
.promo p{margin:4px 0 0;font:400 .875rem/1.4 var(--font);color:#45190b}
.promo button{flex:none;border:0;cursor:pointer;border-radius:var(--r-s);
  background:var(--accent);color:#fff;padding:12px 18px;font:600 .875rem/1 var(--font)}
.promo button:hover{background:var(--plum-raised)}

/* ---- supply strip ----
   What the feed cannot show: how much is actually out there per gym. Counts are
   punches, not listings, because a pass is the unit someone actually wants. */
.supplyhead{display:flex;align-items:baseline;gap:4px 12px;
  justify-content:space-between;margin:22px 2px 0}
.supplyhead h2{font-size:1.375rem;font-weight:700;letter-spacing:-.02em;line-height:1.15}
.supplyhead span{flex:none;color:var(--muted);font:400 .75rem/1 'DM Mono',ui-monospace,monospace;
  letter-spacing:.1em;text-transform:uppercase}
.supply{display:flex;gap:9px;overflow-x:auto;margin:12px calc(-1*var(--gutter)) 0;padding:2px var(--gutter) 4px;
  scrollbar-width:none}
.supply::-webkit-scrollbar{display:none}
/* Was 7.5rem wide with a 22px count — three tiles filled the screen and the
   number shouted louder than the gym it belonged to. The count is the
   secondary fact here: you scan this strip for a gym, not for a number. */
.gymtile{flex:none;inline-size:4.6rem;text-align:left;border:0;cursor:pointer;font:inherit;
  color:inherit;background:var(--surface);border-radius:var(--r-m);padding:9px 10px;
  box-shadow:var(--lift);transition:box-shadow .15s var(--ease)}
.gymtile .logo{inline-size:28px;block-size:28px;border-radius:9px;font-size:.625rem}
.gymtile .n{display:flex;align-items:baseline;gap:4px;margin-top:8px}
.gymtile .n b{font:600 1rem/1 var(--font);letter-spacing:-.03em;
  font-variant-numeric:tabular-nums}
.gymtile .n span{color:var(--muted);font:400 .625rem/1 var(--font)}
.gymtile em{display:block;margin-top:4px;font-style:normal;font:500 .6875rem/1.25 var(--font);
  overflow-wrap:anywhere}
.gymtile small{display:block;margin-top:2px;color:var(--muted);font:400 .625rem/1.3 var(--font);
  overflow-wrap:anywhere}
/* Selected acts as a filter on the feed below. */
.gymtile[aria-pressed="true"]{box-shadow:0 0 0 2px var(--accent),var(--lift)}
.gymtile[aria-pressed="true"] .n b{color:var(--accent)}
/* Follow control, top-right of each gym tile. */
.gymtile{position:relative}
.fave{position:absolute;top:5px;right:5px;inline-size:22px;block-size:22px;
  display:grid;place-items:center;border-radius:var(--r-full);color:var(--border-strong);
  cursor:pointer}
.fave:hover{color:var(--muted);background:var(--sunken)}
.fave.on{color:var(--accent)}
.fave:focus-visible{outline:2px solid var(--focus);outline-offset:1px}

/* ---- filter chips ---- */
.filters{display:flex;gap:7px;overflow-x:auto;padding:14px 0 4px;margin:0 calc(-1*var(--gutter));
  padding-inline:var(--gutter);scrollbar-width:none}
.filters::-webkit-scrollbar{display:none}
.chip{flex:none;border:1px solid var(--hair);border-radius:var(--r-full);background:var(--surface);
  padding:8px 14px;font:500 .8125rem/1 var(--font);color:var(--muted);cursor:pointer;
  transition:background .15s var(--ease),color .15s var(--ease),border-color .15s var(--ease)}
.chip[aria-pressed="true"]{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}

/* ---- view toggle ---- */
.countrow{display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin:18px 2px 12px}
/* The count lives in the section heading now; the row keeps only the switch. */
.countrow .count{display:none}
.countrow{justify-content:flex-start}
.count{margin:0}

/* ---- list view ----
   Same markup, reflowed: the parts that help you decide stay, the prose goes.
   A list is for comparing many at a glance; a card is for reading one. */
#cards.list{display:grid;gap:8px;grid-template-columns:minmax(0,1fr)}
#cards.list .card{margin:0;padding:14px 16px;display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:14px}
#cards.list .card-h{display:contents}
#cards.list .card-h > div:first-of-type{grid-column:2;min-width:0}
#cards.list .logo{grid-column:1;inline-size:38px;block-size:38px}
#cards.list .card-h h3{font-size:.9375rem}
#cards.list .card-h .who{margin-top:4px;font-size:.75rem;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
#cards.list .state{grid-column:3;grid-row:1;justify-self:end}
#cards.list .stats{grid-column:2 / -1;margin-top:4px;gap:6px}
#cards.list .stat{padding:8px 10px}
#cards.list .stat .v{font-size:.875rem;margin-top:4px}
#cards.list .stat .k{font-size:.625rem}
/* Prose and meta lines are the part a list can do without. */
#cards.list .note,#cards.list .cardpick,#cards.list .vs,#cards.list .setbadge,
#cards.list .meter,#cards.list .meter-l{display:none}
#cards.list .cardfoot{grid-column:1 / -1;margin-top:10px;padding-top:10px}
#cards.list .want{grid-column:2 / -1}

/* ---- listing card ---- */
/* A listing is one of many in a column, so it is drawn with a hairline rather
   than lifted off the page: a stack of shadows reads as clutter. */
.card{width:100%;text-align:left;display:block;background:var(--surface);cursor:pointer;
  border:1px solid var(--hair);border-radius:var(--r-m);padding:16px;margin-top:12px;
  font:inherit;color:inherit}
.card-h{display:flex;align-items:flex-start;gap:12px;flex-wrap:wrap}
/* On a narrow phone the state tag drops to its own line rather than squeezing
   the gym name into a two-line wrap mid-word. */
.card-h > div:first-of-type{flex:1 1 55%;min-width:0}
.card-h h3{text-wrap:balance}
.logo{inline-size:40px;block-size:40px;border-radius:13px;flex:none;display:grid;place-items:center;
  background:var(--accent-soft);color:var(--accent);font:600 .8125rem/1 var(--font);overflow:hidden}
.logo img{inline-size:78%;block-size:78%;object-fit:contain}
/* A brand mark brings its own colour, so it sits on a neutral tile rather than
   the teal tint used behind monograms. */
.logo.brand{background:var(--sunken)}
.card-h h3{font-size:1.0625rem}
.card-h .who{display:block;margin-top:4px;color:var(--muted);font:400 .8125rem/1 var(--font)}
.soon{flex:none;margin-left:auto;color:var(--muted);font:500 .75rem/1 var(--font)}
.soon.warn{color:var(--accent)}
.stats{display:flex;gap:8px;margin-top:16px}
.stat{flex:1;background:var(--sunken);border-radius:var(--r-m);padding:12px 12px}
.stat .k{display:flex;align-items:center;gap:5px;color:var(--muted);font:400 .6875rem/1 var(--font)}
.stat .k svg{flex:none;opacity:.8}
.stat .v{display:block;margin-top:6px;font:600 1.0625rem/1 var(--font);letter-spacing:-.03em;
  font-variant-numeric:tabular-nums}
.note{margin:14px 0 0;color:var(--muted);font:400 .875rem/1.45 var(--font)}
.cardfoot{display:flex;align-items:center;gap:9px;margin-top:16px;padding-top:14px;
  border-top:1px solid var(--hair)}
.face{inline-size:28px;block-size:28px;border-radius:var(--r-full);display:grid;place-items:center;
  font:600 .625rem/1 var(--font);color:var(--on-accent);background:var(--accent);flex:none}
.face.alt{background:var(--text);color:var(--bg)}
.cardfoot .sh{color:var(--muted);font:400 .75rem/1 var(--font)}
.cardfoot .go{margin-left:auto;color:var(--accent);font:500 .8125rem/1 var(--font)}

/* ---- listing state ---- */
.state{flex:none;display:inline-flex;align-items:center;gap:5px;border-radius:var(--r-full);
  padding:6px 10px 6px 8px;font:500 .6875rem/1 var(--font);background:var(--sunken);
  color:var(--muted);white-space:nowrap}
.state svg{flex:none}
/* Colour carries the same meaning as the icon, never on its own. */
.state.open{background:var(--accent-soft);color:var(--accent)}
.state.negotiating{background:var(--sunken);color:var(--warning)}
.state.sold{background:var(--sunken);color:var(--muted)}
.state.mine{background:var(--text);color:var(--bg);padding-inline:10px}
.state.saved{background:var(--accent-soft);color:var(--accent)}
.card-h .state+.state{margin-left:6px}
/* A negotiating listing stays visible — someone may still want to be next in
   line — but it steps back so open ones read first. */
.card.negotiating .stats,.card.negotiating .note{opacity:.62}

.stat .of{color:var(--muted);font-weight:400;font-size:.75rem}
.setbadge{display:inline-flex;margin-top:12px;border-radius:var(--r-full);padding:6px 12px;
  background:var(--sunken);color:var(--muted);font:500 .75rem/1 var(--font)}

/* ---- owner inventory ----
   Punches as tappable pips: marking two of three gone is one tap, and the row
   reads as the card it represents. */
.inv{margin-top:12px;background:var(--sunken);border-radius:var(--r-m);padding:12px}
.inv-h{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.inv-h span{color:var(--muted);font:400 .6875rem/1 var(--font)}
.inv-h b{font:600 .8125rem/1 var(--font)}
.pips-row{display:flex;gap:6px;margin-top:12px}
.pipbtn{flex:1;block-size:34px;border:1.5px solid var(--border-input);background:var(--surface);
  border-radius:var(--r-s);cursor:pointer;display:grid;place-items:center;
  font:600 .75rem/1 var(--font);color:var(--muted);
  transition:background .15s var(--ease),color .15s var(--ease),border-color .15s var(--ease)}
.pipbtn.gone{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.inv-note{margin-top:10px;color:var(--muted);font:400 .6875rem/1.4 var(--font)}
.setbtn{width:100%;margin-top:12px;border:0;cursor:pointer;border-radius:var(--r-full);
  padding:12px;font:500 .8125rem/1 var(--font);background:var(--surface);color:var(--text)}
.setbtn.gone{background:var(--accent);color:var(--on-accent)}

.vs{display:inline-flex;align-items:center;gap:6px;margin-top:10px;border-radius:var(--r-full);
  padding:4px 10px;font:500 .6875rem/1.2 var(--font);background:var(--accent-soft);color:var(--accent)}
.vs.bad{background:var(--sunken);color:var(--warning)}

/* ---- pickup ----
   Where the handover happens. On a pass card this is not a detail: the owner
   often has to check you in at the desk themselves. */
.pickup{display:flex;align-items:flex-start;gap:9px;margin-top:14px;
  color:var(--muted);font:400 .8125rem/1.4 var(--font)}
.pickup svg{flex:none;margin-top:1px}
.pickup b{color:var(--text);font-weight:500}
.cardpick{display:flex;align-items:flex-start;gap:6px;margin-top:12px;color:var(--muted);
  font:400 .75rem/1.4 var(--font);min-width:0;overflow-wrap:anywhere}
.cardpick svg{flex:none;margin-top:.15em}
/* Days remaining is the number that decides whether a listing is worth acting
   on, so it keeps its own weight even inside the muted meta line. */
.daysleft{color:var(--text);font-weight:500}
.daysleft.soon{color:var(--danger)}

/* ---- offer composer (requester side) ---- */
.offerbox{margin-top:18px;background:var(--sunken);border-radius:var(--r-m);padding:14px 16px}
.offerrow{display:flex;align-items:center;gap:12px}
.offerrow label{flex:1;min-width:0}
.offerrow span{display:block;color:var(--muted);font:400 .6875rem/1 var(--font)}
.offerrow input{inline-size:100%;border:0;background:none;color:var(--text);padding:6px 0 0;
  font:600 1.25rem/1 var(--font);letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.stepper{display:flex;align-items:center;gap:2px;background:var(--surface);
  border-radius:var(--r-full);padding:4px}
.stepper button{inline-size:30px;block-size:30px;margin-block:-4px;border:0;background:none;cursor:pointer;
  border-radius:var(--r-full);color:var(--text);font:600 1rem/1 var(--font)}
.stepper button:disabled{color:var(--muted);opacity:.4;cursor:default}
.stepper b{min-inline-size:22px;text-align:center;font:600 .875rem/1 var(--font);
  font-variant-numeric:tabular-nums}
.askline{margin-top:12px;color:var(--muted);font:400 .75rem/1.4 var(--font)}
.askline b{color:var(--text);font-weight:600}

.offerrow label em{font-style:normal;color:var(--muted);font-weight:400}
#offersug{margin-top:12px}

/* ---- incoming requests (owner side) ---- */
.req-in{display:flex;gap:11px;align-items:flex-start;padding:14px 0;
  border-top:1px solid var(--hair)}
.req-in:first-child{border-top:0}
.req-t{flex:1;min-width:0}
.req-t b{font:600 .875rem/1 var(--font)}
.req-t p{margin:6px 0 0;color:var(--muted);font:400 .75rem/1.4 var(--font)}
.req-t .amt{color:var(--text);font-weight:600;font-variant-numeric:tabular-nums}
.req-t .under{color:var(--warning)}
.req-acts{display:flex;gap:7px;margin-top:12px}
.req-acts button{border:0;cursor:pointer;border-radius:var(--r-full);padding:10px 16px;
  font:500 .8125rem/1 var(--font)}
.acc{background:var(--accent);color:var(--on-accent)}
.dec{background:var(--sunken);color:var(--muted)}
.req-done{margin-top:10px;font:500 .75rem/1 var(--font)}
.req-done.yes{color:var(--success)}
.req-done.no{color:var(--muted)}
.pend{background:var(--accent-soft);color:var(--accent);border-radius:var(--r-full);
  padding:4px 10px;font:500 .6875rem/1 var(--font)}

/* ---- owner's listing detail ---- */
.owned-sub{display:block;margin-top:4px;color:var(--muted);font:400 .75rem/1 var(--font)}
.owned-stats{display:flex;gap:7px;margin-top:12px}
.owned-stats .s{flex:1;background:var(--sunken);border-radius:var(--r-m);padding:10px 12px}
.owned-stats .k{display:block;color:var(--muted);font:400 .625rem/1 var(--font)}
.owned-stats .v{display:block;margin-top:6px;font:600 1rem/1 var(--font);letter-spacing:-.03em;
  font-variant-numeric:tabular-nums}
.owned-meta{margin-top:12px;display:grid;gap:8px}
.mrow{display:flex;align-items:center;gap:8px;color:var(--muted);font:400 .75rem/1.35 var(--font)}
.mrow svg{flex:none}
.mrow b{color:var(--text);font-weight:500}
/* An expiring pass is worth nothing the day after, so the countdown is the one
   thing on this card allowed to shout. */
.mrow.soon{color:var(--danger)}
.mrow.soon b{color:var(--danger)}
.mrow.has b{color:var(--accent)}

/* ---- editing your own pickup ----
   Your own listing: the pickup row is a control, not a label. Everyone else's
   stays plain text. */
.mrow.edit{width:100%;text-align:left;border:0;background:none;padding:0;cursor:pointer;
  font:inherit;color:var(--muted);align-items:center}
.mrow.edit .pen{margin-left:auto;color:var(--accent);font:500 .75rem/1 var(--font)}
.pickedit{margin-top:12px;background:var(--sunken);border-radius:var(--r-m);padding:12px}
.pickedit label{display:block;color:var(--muted);font:400 .6875rem/1 var(--font)}
.pickedit input{inline-size:100%;margin-top:8px;border:1px solid var(--border-input);
  background:var(--surface);color:var(--text);border-radius:var(--r-s);padding:12px 12px;
  font:400 .875rem/1 var(--font)}
.picksug{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.picksug button{border:1px solid var(--hair);background:var(--surface);color:var(--muted);
  border-radius:var(--r-full);padding:8px 12px;font:400 .75rem/1 var(--font);cursor:pointer}
/* These are a choice, not a list of suggestions, so one of them is always the
   answer and has to look like it. Without this the default was selected in the
   data and unmarked on screen. */
.picksug button[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);
  color:var(--on-accent);font-weight:600}
.pickacts{display:flex;gap:7px;margin-top:12px}
.pickacts button{border:0;cursor:pointer;border-radius:var(--r-full);padding:10px 16px;
  font:500 .8125rem/1 var(--font)}
.pickacts .save{background:var(--accent);color:var(--on-accent)}
.pickacts .cancel{background:var(--surface);color:var(--muted)}

/* ---- owner's state switch ---- */
.owned{background:var(--surface);border-radius:var(--r-l);padding:16px;box-shadow:var(--lift);
  margin-top:10px}
.owned-h{display:flex;align-items:center;gap:11px}
.owned-h .logo{inline-size:34px;block-size:34px;border-radius:11px;font-size:.6875rem}
.owned-t{flex:1;min-width:0}
.owned-t b{display:block;font:600 .9375rem/1 var(--font);letter-spacing:-.02em}
.owned-t span{display:block;margin-top:4px;color:var(--muted);font:400 .75rem/1 var(--font)}
.switch{display:flex;flex-wrap:wrap;gap:3px;margin-top:12px;padding:4px;
  background:var(--sunken);border-radius:var(--r-full)}
.switch button{flex:1 1 6rem;min-width:0;border:0;background:none;cursor:pointer;border-radius:var(--r-full);
  padding:10px 6px;font:500 .75rem/1 var(--font);color:var(--muted);
  transition:background .18s var(--ease),color .18s var(--ease)}
.switch button[aria-pressed="true"]{background:var(--surface);color:var(--text);
  box-shadow:0 1px 2px rgb(28 15 43/.07)}
.switch button[aria-pressed="true"][data-s="negotiating"]{color:var(--warning)}
.switch button[aria-pressed="true"][data-s="sold"]{color:var(--muted)}
.selfnote{margin:14px 2px 0;color:var(--muted);font:400 .75rem/1.45 var(--font)}

/* ---- detail ---- */
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:4px}
/* The one loud control on a screen: ember, which carries ink rather than
   white, because white on ember is unreadable. */
.btn{display:block;width:100%;border:0;cursor:pointer;background:var(--hot);color:var(--on-hot);
  border-radius:var(--r-full);padding:16px;font:600 .9375rem/1 var(--font);letter-spacing:-.01em;
  margin-top:18px;transition:opacity .15s var(--ease)}
.btn:disabled{opacity:.5;cursor:default}
.btn.ghost{background:var(--sunken);color:var(--text)}
/* Spare is not an escrow. Say so where the money is mentioned. */
.offline{display:flex;gap:10px;align-items:flex-start;margin-top:14px;color:var(--muted);
  font:400 .8125rem/1.45 var(--font)}
.offline svg{flex:none;margin-top:1px}
/* One vertical rhythm for section headings: 28 above, 12 below, everywhere. */
.seclabel{margin:28px 0 12px;font-size:.9375rem}
.empty{background:var(--sunken);border-radius:var(--r-m);padding:16px;color:var(--muted);
  font:400 .875rem/1.45 var(--font)}
.thread{display:grid;gap:9px}
.msg{max-width:82%;padding:12px 14px;border-radius:var(--r-m);font:400 .875rem/1.4 var(--font)}
.msg.them{background:var(--sunken)}
.msg.me{background:var(--accent);color:var(--on-accent);margin-left:auto}
.composer{display:flex;gap:8px;margin-top:12px}
.composer input{flex:1;min-width:0;background:var(--surface);border:1px solid var(--hair);
  border-radius:var(--r-full);padding:12px 16px;font:400 .875rem/1 var(--font);color:var(--text)}
.composer button{flex:none;border:0;cursor:pointer;background:var(--accent);color:var(--on-accent);
  border-radius:var(--r-full);padding:0 20px;font:600 .875rem/1 var(--font)}

/* ---- post form ---- */
.field{display:block;margin-top:10px;background:var(--surface);border-radius:var(--r-m);
  padding:12px 16px;box-shadow:var(--lift)}
.field span{display:block;color:var(--muted);font:400 .75rem/1 var(--font)}
.field input,.field select{width:100%;border:0;background:none;color:var(--text);padding:6px 0 0;
  font:500 1rem/1.2 var(--font);-webkit-appearance:none;appearance:none}
.field .opt{color:var(--muted)}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.row2 .field{margin-top:0}

/* ---- profile photo ---- */
.avatar-edit{position:relative;flex:none;border:0;background:none;padding:0;cursor:pointer;
  border-radius:var(--r-full);line-height:0}
.avatar-edit .face{inline-size:56px;block-size:56px;font-size:1.0625rem;overflow:hidden}
.face img{inline-size:100%;block-size:100%;object-fit:cover;display:block}
.avatar-cam{position:absolute;right:-2px;bottom:-2px;inline-size:24px;block-size:24px;
  border-radius:var(--r-full);display:grid;place-items:center;background:var(--accent);
  color:var(--on-accent);box-shadow:0 0 0 2.5px var(--bg)}
.avatar-edit:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
.avatar-actions{display:flex;gap:8px;margin-top:12px}
.avatar-actions button{border:1px solid var(--hair);background:var(--surface);
  color:var(--text);cursor:pointer;border-radius:var(--r-full);padding:10px 14px;
  font:500 .8125rem/1 var(--font)}
.avatar-actions button.danger{color:var(--danger);border-color:var(--hair)}
.avatar-err{margin-top:10px;color:var(--danger);font:500 .75rem/1.4 var(--font)}

/* ---- profile ---- */
.pro{display:flex;align-items:center;gap:14px;margin-top:8px}
.pro .face{inline-size:56px;block-size:56px;font-size:1.0625rem}
/* Scoped to the text block: a bare `.pro span` also matched the avatar, whose
   own display:grid it overrode — which left the initials stuck in its corner. */
.pro > div > b{display:block;font:600 1.3125rem/1 var(--font);letter-spacing:-.03em}
.pro > div > span{display:block;margin-top:6px;color:var(--muted);
  font:400 .875rem/1 var(--font)}
.give{margin-top:18px;background:var(--surface);border-radius:var(--r-l);padding:18px;box-shadow:var(--lift)}
.give-n{display:flex;align-items:baseline;gap:9px}
.give-n b{font:600 2.125rem/1 var(--font);letter-spacing:-.045em;font-variant-numeric:tabular-nums}
.give-n span{color:var(--muted);font:400 .875rem/1.3 var(--font)}
.give p{margin:12px 0 0;font:400 .875rem/1.45 var(--font)}
.list{margin-top:10px;background:var(--surface);border-radius:var(--r-l);padding:4px 18px;
  box-shadow:var(--lift)}
.item{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding:16px 0;
  border-top:1px solid var(--hair)}
/* A settings row is a label and a control. They sit side by side while both
   fit; once the text is large enough that they cannot, the control takes its
   own full-width line rather than pushing the screen sideways. */
.item > .switch,.item > .fxrow{flex:1 1 100%;min-width:0}
.item:first-child{border-top:0}
/* The label takes the free space so the value or chevron sits at the end —
   with an icon added, space-between was stranding it in the middle. */
.item .k{flex:1;text-align:left;color:var(--muted);font:400 .875rem/1 var(--font)}
.item .v{margin-left:auto;font:500 .875rem/1 var(--font);text-align:right}
.item .v.sub{color:var(--muted);font-weight:400}
.tagp{border-radius:var(--r-full);padding:6px 10px;font:500 .6875rem/1 var(--font);
  background:var(--sunken);color:var(--muted)}
.tagp.open{background:var(--accent-soft);color:var(--accent)}
.foot-note{margin:16px 2px 0;color:var(--muted);font:400 .8125rem/1.45 var(--font)}

/* ---- auth ----
   No bottom nav here: a signed-out person has nowhere to navigate to. */
body.auth .nav{display:none}
.auth-wrap{padding-top:34px}
.auth-mark{font-size:2.5rem;font-weight:600;letter-spacing:-.05em}
.auth-lede{margin:10px 0 0;color:var(--muted);font:400 1rem/1.45 var(--font);
  max-inline-size:30ch}
.auth-form{margin-top:30px;display:grid;gap:10px}
.auth-form .field{margin:0}
.auth-alt{margin-top:22px;text-align:center;color:var(--muted);font:400 .875rem/1 var(--font)}
.auth-alt button{border:0;background:none;cursor:pointer;color:var(--accent);
  font:600 .875rem/1 var(--font);padding:0}
.or{display:flex;align-items:center;gap:12px;margin:20px 0;color:var(--muted);
  font:400 .75rem/1 var(--font)}
.or::before,.or::after{content:"";flex:1;border-top:1px solid var(--hair)}
.oauth{display:grid;gap:9px}
/* Provider marks keep their own brand colour — Google and LINE both require it,
   and a recoloured mark reads as a knock-off. */
.obtn{display:flex;align-items:center;gap:12px;width:100%;
  border:1px solid var(--hair);background:var(--surface);color:var(--text);cursor:pointer;
  border-radius:var(--r-full);padding:14px 18px;font:500 .9375rem/1 var(--font)}
.obtn svg{flex:none}
/* A provider the project has not enabled. Still readable, still tappable —
   tapping explains — but it no longer looks like a door that opens. */
.obtn.off{opacity:.5}
.obtn.off svg{filter:grayscale(1)}
.obtn span{flex:1;text-align:center;margin-right:18px}
/* On sign-up they sit in a row, so the label shortens to the provider name. */
#su-social{grid-template-columns:repeat(3,1fr);gap:8px}
#su-social .obtn{flex-direction:column;gap:7px;padding:12px 6px;font-size:.8125rem}
#su-social .obtn span{margin:0;text-align:center}
/* The consent checkbox is a real input: it must be reachable and announced. */
.consent{display:flex;gap:11px;align-items:flex-start;margin-top:18px;
  color:var(--muted);font:400 .8125rem/1.45 var(--font)}
.consent input{appearance:none;-webkit-appearance:none;margin:1px 0 0;flex:none;
  inline-size:22px;block-size:22px;border-radius:7px;border:1.5px solid var(--border-input);
  background:var(--surface);cursor:pointer;position:relative}
.consent input:checked{background:var(--accent);border-color:var(--accent)}
.consent input:checked::after{content:"";position:absolute;left:7px;top:3px;inline-size:5px;
  block-size:10px;border:solid var(--on-accent);border-width:0 2px 2px 0;transform:rotate(45deg)}
.consent input:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.consent button{border:0;background:none;padding:0;cursor:pointer;color:var(--accent);
  font:inherit;font-weight:500;text-decoration:underline}

/* ---- splash and coming soon ----
   Named `comingsoon`, not `soon`: a listing's "expiring soon" label already
   owns `.soon`, and a full-screen plum panel inherited by every expiring card
   is exactly as bad as it sounds.

   From the brand deck, Option 2 in plum and ember: the pass-link loader, then
   the start screen. Timings and colours are the deck's own. */
.splash,.comingsoon{position:fixed;inset:0;z-index:60;background:#2b1640;color:#fff;
  padding:env(safe-area-inset-top,0px) 24px env(safe-area-inset-bottom,0px)}
.splash{display:grid;place-items:center;transition:opacity .45s var(--ease);z-index:61}
.splash[hidden],.comingsoon[hidden]{display:none}
.splash.gone{opacity:0;pointer-events:none}
.splash-in{display:flex;flex-direction:column;align-items:center;gap:40px}
.sp-loader{inline-size:124px;display:block;overflow:visible}
.ln-pulse{transform-origin:210px 510px;animation:lnPulse 4s cubic-bezier(.45,0,.2,1) infinite}
.ln-front,.ln-back{transform-box:fill-box;transform-origin:50% 50%}
.ln-front{animation:lnFront 4s cubic-bezier(.45,0,.2,1) infinite}
.ln-back{animation:lnBack 4s cubic-bezier(.45,0,.2,1) infinite}
.ln-gap{stroke-dasharray:1;animation:lnGap 4s cubic-bezier(.45,0,.2,1) infinite}
.sp-bar{inline-size:72px;block-size:3px;border-radius:2px;background:#452a5c;overflow:hidden}
.sp-bar i{display:block;inline-size:40%;block-size:100%;border-radius:2px;background:#ff6b3d;
  animation:ldBar 1.3s ease-in-out infinite}
.splash .foot{position:absolute;inset-inline:0;bottom:calc(52px + env(safe-area-inset-bottom,0px));
  text-align:center;font:400 11px/1 'DM Mono',ui-monospace,monospace;letter-spacing:.14em;color:#d9c6e6}
@keyframes lnBack{0%{opacity:0;transform:translate(0,-42px) scale(.85)}12%,30%{opacity:1;transform:translate(0,-42px)}50%,86%{opacity:1;transform:translate(0,0)}96%,100%{opacity:0;transform:translate(0,0)}}
@keyframes lnFront{0%{opacity:0;transform:translate(0,42px) scale(.85)}12%,30%{opacity:1;transform:translate(0,42px)}50%,86%{opacity:1;transform:translate(0,0)}96%,100%{opacity:0;transform:translate(0,0)}}
@keyframes lnGap{0%,48%{stroke-dashoffset:0}58%,100%{stroke-dashoffset:1}}
@keyframes lnPulse{0%,58%{transform:scale(1)}64%{transform:scale(1.06)}72%,100%{transform:scale(1)}}
@keyframes ldBar{0%{transform:translateX(-100%)}100%{transform:translateX(250%)}}
@keyframes spIn{from{opacity:0;transform:translateY(14px) scale(.94)}to{opacity:1;transform:none}}

.comingsoon{display:flex;flex-direction:column;overflow-y:auto}
.soon-mid{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:44px;padding:48px 8px 24px}
.soon-logo{inline-size:210px;display:block}
/* The entrance waits for the splash to hand over, rather than playing unseen beneath it. */
.comingsoon.in .soon-logo{animation:spIn .9s cubic-bezier(.2,.8,.2,1) both}
.soon-copy{display:flex;flex-direction:column;align-items:center;gap:12px;text-align:center}
.comingsoon.in .soon-copy{animation:spIn .9s cubic-bezier(.2,.8,.2,1) .15s both}
.soon-copy h1{font:600 30px/1.15 'Onest',var(--font);letter-spacing:-.02em;text-wrap:balance;max-inline-size:12ch}
.soon-copy p{margin:0;font:400 16px/1.5 'Onest',var(--font);color:#eadcf2}
.soon-foot{display:flex;flex-direction:column;align-items:center;gap:14px;
  padding:0 0 28px;inline-size:100%;max-inline-size:342px;margin-inline:auto}
.comingsoon.in .soon-foot{animation:spIn .9s cubic-bezier(.2,.8,.2,1) .3s both}
.soon-badge{margin:0 0 4px;text-align:center;color:#ff6b3d;font:700 24px/1.2 'Onest',var(--font);letter-spacing:-.01em}
.soon-form{inline-size:100%;display:flex;flex-direction:column;gap:8px;margin-top:6px}
.soon-lbl{font:500 13px/1.3 'Onest',var(--font);color:#eadcf2;text-align:center}
.soon-row{display:flex;gap:8px}
.soon-row input{flex:1 1 0;min-inline-size:0;block-size:52px;padding:0 16px;border-radius:14px;
  border:1px solid #6e5287;background:#36204d;color:#fff;font:400 16px/1 'Onest',var(--font)}
.soon-row input::placeholder{color:#a892bb}
.soon-row input:focus{outline:none;border-color:#ffc2d4}
.soon-row input[aria-invalid="true"]{border-color:#ff8a63}
.soon-row button{flex:none;block-size:52px;padding:0 18px;border:0;border-radius:14px;cursor:pointer;
  background:#ffc2d4;color:#1c0f2b;font:600 15px/1 'Onest',var(--font)}
.soon-row button:hover{background:#ffd6e2}
.soon-row button:disabled{opacity:.6;cursor:default}
.busy::before{content:"";display:inline-block;vertical-align:-2px;margin-inline-end:9px;
  inline-size:14px;block-size:14px;border-radius:50%;
  border:2px solid currentColor;border-inline-end-color:transparent;opacity:.8;
  animation:soonSpin .7s linear infinite}
.soon-row button.busy{display:inline-flex;align-items:center;gap:9px;opacity:1}
.soon-row button.busy::before{content:"";inline-size:15px;block-size:15px;border-radius:50%;
  border:2px solid rgba(28,15,43,.25);border-top-color:#1c0f2b;animation:soonSpin .7s linear infinite}
@keyframes soonSpin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.soon-row button.busy::before{animation-duration:2.4s}}
.soon-row button:focus-visible{outline:2px solid #ffc2d4;outline-offset:3px}
.soon-msg{margin:0;min-block-size:1.4em;text-align:center;font:500 13px/1.4 'Onest',var(--font);color:#ffc2d4}
.soon-msg.bad{color:#ffb39a}
.comingsoon.done .soon-copy,.comingsoon.done .soon-form,.comingsoon.done .soon-badge{display:none}
.soon-done{display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center;
  padding:0 8px 32px;animation:spIn .7s cubic-bezier(.2,.8,.2,1) both}
.soon-done[hidden]{display:none}
.soon-done-h{margin:0;font:600 34px/1.1 'Onest',var(--font);letter-spacing:-.02em;color:#fff;outline:none}
.soon-done-s{margin:0;font:600 22px/1.2 'Onest',var(--font);color:#ff6b3d}
.soon-done-n{margin:8px 0 0;font:400 15px/1.5 'Onest',var(--font);color:#eadcf2}
.soon-ig{display:flex;align-items:center;justify-content:center;inline-size:100%;block-size:56px;
  border:1px solid #6e5287;border-radius:16px;color:#fff;text-decoration:none;font:500 15px/1 'Onest',var(--font)}
.soon-ig{gap:10px}
.soon-ig .ig-ico{flex:none}
.soon-ig:hover{border-color:#fff}
.soon-ig:focus-visible{outline:2px solid #ffc2d4;outline-offset:3px}
.soon-legal{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 18px;
  padding:18px 0 calc(22px + env(safe-area-inset-bottom,0px));border-top:1px solid #452a5c;
  inline-size:100%;max-inline-size:560px;margin-inline:auto;
  font:400 12px/1.4 'Onest',var(--font);color:#a892bb}
.soon-legal a{color:#d9c6e6;text-decoration:none}
.soon-legal a:hover{color:#fff;text-decoration:underline}
.soon-legal a:focus-visible{outline:2px solid #ffc2d4;outline-offset:2px;border-radius:4px}
.soon-city{padding-top:8px;font:400 11px/1 'DM Mono',ui-monospace,monospace;letter-spacing:.14em;color:#d9c6e6}
body.soonmode{overflow:hidden}
@media (prefers-reduced-motion:reduce){
  .ln-pulse,.ln-front,.ln-back,.ln-gap,.sp-bar i,.comingsoon.in .soon-logo,.comingsoon.in .soon-copy,.comingsoon.in .soon-foot{animation:none}
}
.rail-empty{display:none}


/* ---- website footer ----
   Desktop only. On a phone the short sign-off already does this job, and a
   four-column footer at the end of an infinite feed is just scroll. */
.sitefoot{display:none}

/* The desktop site footer that lived here served the two-column shell; the
   phone sign-off (.appfoot) now serves every width. */

/* ---- someone else's profile ---- */
.uhead{display:flex;align-items:center;gap:15px;margin-top:6px}
.uhead .face{inline-size:60px;block-size:60px;font-size:1.125rem}
/* Scoped to the text block — a bare `.uhead span` also matches the avatar and
   overrides its display:grid, which strands the initials in its corner. */
.uhead > div > b{display:block;font:600 1.3125rem/1 var(--font);letter-spacing:-.03em}
.uhead > div > span{display:block;margin-top:6px;color:var(--muted);
  font:400 .8125rem/1.35 var(--font)}
.ustats{display:flex;gap:9px;margin-top:20px}
.ustat{flex:1;background:var(--surface);border-radius:var(--r-l);padding:16px;
  box-shadow:var(--lift)}
.ustat .v{font:600 1.375rem/1 var(--font);letter-spacing:-.04em;font-variant-numeric:tabular-nums}
.ustat .k{display:block;margin-top:8px;color:var(--muted);font:400 .6875rem/1.3 var(--font)}
/* Who you're meeting is the point of this screen, so the trust line is stated
   rather than implied by a number. */
.trust{display:flex;gap:10px;align-items:flex-start;margin-top:16px;color:var(--muted);
  font:400 .8125rem/1.5 var(--font)}
.trust svg{flex:none;margin-top:2px;color:var(--accent)}
.who-link{cursor:pointer;text-decoration:underline;text-underline-offset:2px;
  text-decoration-color:var(--border-strong)}

.u-actions{display:flex;gap:8px;margin-top:16px}
.u-actions button{border:1px solid var(--hair);background:var(--surface);cursor:pointer;
  border-radius:var(--r-full);padding:10px 16px;font:500 .8125rem/1 var(--font);
  color:var(--muted);position:relative}
.u-actions button::after{content:"";position:absolute;left:50%;top:50%;
  transform:translate(-50%,-50%);inline-size:max(100%,44px);block-size:max(100%,44px)}
.u-actions .u-block.on{background:var(--text);color:var(--bg);border-color:var(--text)}
.blocklist{background:var(--surface);border-radius:var(--r-l);padding:4px 18px;
  box-shadow:var(--lift);margin-top:10px}
.blockrow{display:flex;align-items:center;gap:12px;padding:12px 0;
  border-top:1px solid var(--hair)}
.blockrow:first-child{border-top:0}
.blockrow b{flex:1;font:500 .875rem/1 var(--font)}
.blockrow button{border:0;background:var(--sunken);color:var(--text);cursor:pointer;
  border-radius:var(--r-full);padding:10px 14px;font:500 .8125rem/1 var(--font)}
.blockempty{padding:16px 0;color:var(--muted);font:400 .8125rem/1.5 var(--font)}


/* ---- dashboard ---------------------------------------------------------- */
.adtabs{display:flex;gap:6px;margin:14px 0 4px}
.adtab{flex:1;padding:9px 10px;border:0;border-radius:11px;background:var(--sunken);
  color:var(--muted);font:600 .75rem/1.25 var(--font);cursor:pointer}
.adtab.on{background:var(--accent);color:var(--on-accent)}
.adboard{display:none}.adboard.on{display:block}

.adhero{margin:14px 0;padding:16px;border-radius:16px;background:var(--accent);
  color:var(--on-accent);box-shadow:var(--lift)}
.adhero b{display:block;font:700 2.125rem/1 var(--font);font-variant-numeric:tabular-nums}
.adhero .k{display:block;font:600 .75rem/1.3 var(--font);opacity:.85;margin-bottom:6px}
.adhero p{margin:8px 0 0;font:400 .7188rem/1.5 var(--font);opacity:.9}

.adtiles{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin:10px 0}
.adtile{padding:12px;border-radius:13px;background:var(--surface);box-shadow:0 0 0 1px var(--hair)}
.adtile b{display:block;font:700 1.3125rem/1.1 var(--font);color:var(--text);
  font-variant-numeric:tabular-nums}
.adtile span{display:block;font:600 .6562rem/1.35 var(--font);color:var(--muted);margin-top:3px}

.adsec{margin:18px 0 6px;font:700 .8125rem/1.3 var(--font);color:var(--text)}
.adsub{margin:0 0 10px;font:400 .7188rem/1.5 var(--font);color:var(--muted)}

.adrow{display:grid;grid-template-columns:1fr auto;gap:8px;align-items:center;
  padding:7px 0;border-bottom:1px solid var(--hair);font:500 .75rem/1.3 var(--font)}
.adrow:last-child{border-bottom:0}
.adrow .v{font-variant-numeric:tabular-nums;color:var(--text);font-weight:600}
.adbar{grid-column:1/-1;height:6px;border-radius:3px;background:var(--sunken);overflow:hidden}
.adbar i{display:block;height:100%;border-radius:3px;background:var(--c-in)}

/* Two series, two hues, each also carrying its own text label — identity is
   never left to colour alone. */
.adpair{padding:9px 0;border-bottom:1px solid var(--hair)}
.adpair:last-child{border-bottom:0}
.adpair .lbl{font:600 .75rem/1.3 var(--font);color:var(--text);margin-bottom:6px}
.adpair .ln{display:grid;grid-template-columns:70px 1fr auto;gap:8px;
  align-items:center;margin-top:4px;font:500 .6875rem/1.2 var(--font);color:var(--muted)}
.adpair .tr{height:8px;border-radius:4px;background:var(--sunken);overflow:hidden}
.adpair .tr i{display:block;height:100%;border-radius:4px}
.adpair .ln.v .tr i{background:var(--c-out)}
.adpair .ln.m .tr i{background:var(--c-in)}
.adpair .n{font-variant-numeric:tabular-nums;font-weight:700;color:var(--text)}
.adkey{display:flex;gap:14px;margin:2px 0 10px;font:600 .6875rem/1.2 var(--font);color:var(--muted)}
.adkey span{display:flex;align-items:center;gap:5px}
.adkey i{width:9px;height:9px;border-radius:3px;display:block}

.adfun{margin:6px 0}
.adstep{display:grid;grid-template-columns:1fr auto;gap:8px;align-items:baseline;
  padding:8px 10px;border-radius:10px;background:var(--surface);margin-bottom:4px;
  box-shadow:0 0 0 1px var(--hair);font:600 .75rem/1.3 var(--font);color:var(--text)}
.adstep .n{font-variant-numeric:tabular-nums;color:var(--text)}
.adstep small{display:block;font:400 .6562rem/1.4 var(--font);color:var(--muted);margin-top:2px}
.addrop{font:600 .6562rem/1 var(--font);color:var(--warning);margin:0 0 6px 10px}

.adnote{margin:18px 0 0;padding:11px 13px;border-radius:12px;background:var(--accent-soft);
  font:400 .6875rem/1.55 var(--font);color:var(--muted)}

/* ---- onboarding ----
   A short journey: what this is, how a hand-off actually works, then the two
   things the feed needs to be useful on first open. */
/* Not 100dvh: inside the device frame that measures the browser window, not the
   phone, and pushed the buttons past the bottom of the screen. The actions stick
   to the foot of the viewport instead, so they're reachable at any content length. */
.ob{display:flex;flex-direction:column;padding-bottom:6px}
.ob-top{display:flex;align-items:center;gap:12px;padding:18px 0 6px}
.dots{display:flex;gap:6px;flex:1}
.dots i{block-size:4px;flex:1;border-radius:var(--r-full);background:var(--sunken);
  transition:background .3s var(--ease)}
.dots i.on{background:var(--accent)}
.skip{border:0;background:none;padding:0;cursor:pointer;color:var(--muted);
  font:500 .8125rem/1 var(--font)}
.ob-body{flex:1;padding-top:26px;min-block-size:56vh}
.ob-step{display:none}
.ob-step.on{display:block}
.ob h2{font:600 1.6875rem/1.2 var(--font);letter-spacing:-.035em;text-wrap:balance}
.ob .sub{margin:12px 0 0;color:var(--muted);font:400 1rem/1.5 var(--font)}
.ob-actions{position:sticky;bottom:0;z-index:2;display:flex;gap:10px;align-items:center;
  padding-block:16px calc(16px + env(safe-area-inset-bottom,0px));background:var(--bg)}
.ob-actions .btn{margin:0}
.ob-back{flex:none;border:0;background:var(--sunken);color:var(--text);cursor:pointer;
  border-radius:var(--r-full);inline-size:52px;block-size:52px;display:grid;place-items:center}

/* the journey itself */
.journey{margin-top:26px;display:grid;gap:0}
.jstep{display:flex;gap:15px;align-items:flex-start;position:relative;padding-bottom:22px}
.jstep:last-child{padding-bottom:0}
/* The connector is drawn behind the node, so the line reads as one thread. */
.jstep::before{content:"";position:absolute;left:19px;top:38px;bottom:0;inline-size:2px;
  background:var(--hair)}
.jstep:last-child::before{display:none}
.jnode{inline-size:38px;block-size:38px;border-radius:var(--r-full);flex:none;
  display:grid;place-items:center;background:var(--accent-soft);color:var(--accent);
  position:relative;z-index:1}
.jstep.lit .jnode{background:var(--accent);color:var(--on-accent)}
.jt{flex:1;padding-top:2px}
.jt b{display:block;font:600 1rem/1.25 var(--font);letter-spacing:-.02em}
.jt span{display:block;margin-top:6px;color:var(--muted);font:400 .875rem/1.45 var(--font)}

/* gym picker */
.gympick{margin-top:20px;display:grid;gap:8px;max-block-size:46vh;overflow-y:auto;
  scrollbar-width:none}
.gympick::-webkit-scrollbar{display:none}
.gymrow{display:flex;align-items:center;gap:12px;width:100%;text-align:left;cursor:pointer;
  border:1.5px solid var(--hair);background:var(--surface);border-radius:var(--r-m);
  padding:12px 14px;font:inherit;color:inherit;transition:border-color .15s var(--ease)}
.gymrow[aria-pressed="true"]{border-color:var(--accent);background:var(--accent-soft)}
.gymrow .logo{inline-size:34px;block-size:34px;border-radius:11px;font-size:.6875rem}
/* Named, not `.gymrow span`: that selector also matched the gym logo beside it. */
.gymrow-t b{display:block;font:500 .875rem/1 var(--font)}
.gymrow-t span{display:block;margin-top:4px;color:var(--muted);font:400 .75rem/1 var(--font)}
.gymrow .tick{margin-left:auto;color:var(--accent);opacity:0;transition:opacity .15s var(--ease)}
.gymrow[aria-pressed="true"] .tick{opacity:1}

/* discipline chips */
.pickchips{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}
.pickchips button{border:1.5px solid var(--hair);background:var(--surface);color:var(--muted);
  border-radius:var(--r-full);padding:12px 16px;font:500 .875rem/1 var(--font);cursor:pointer;
  transition:border-color .15s var(--ease),color .15s var(--ease),background .15s var(--ease)}
.pickchips button[aria-pressed="true"]{border-color:var(--accent);background:var(--accent);
  color:var(--on-accent)}
.obnote{margin-top:16px;color:var(--muted);font:400 .8125rem/1.5 var(--font)}

/* summary */
.sumcard{margin-top:22px;background:var(--surface);border-radius:var(--r-l);padding:4px 18px;
  box-shadow:var(--lift)}
.sumrow{display:flex;align-items:center;gap:12px;padding:16px 0;border-top:1px solid var(--hair)}
.sumrow:first-child{border-top:0}
.sumrow .k{color:var(--muted);font:400 .8125rem/1 var(--font)}
.sumrow .v{margin-left:auto;font:500 .8125rem/1 var(--font);text-align:right}

/* ---- fields with an icon ----
   A leading glyph per field so the form is scannable rather than a stack of
   identical boxes. */
.ifield{display:flex;align-items:center;gap:12px;margin:0;background:var(--surface);
  border:1.5px solid var(--hair);border-radius:var(--r-m);padding:12px 14px;
  box-shadow:var(--lift);transition:border-color .15s var(--ease)}
.ifield:focus-within{border-color:var(--accent)}
.fico{inline-size:36px;block-size:36px;border-radius:11px;flex:none;display:grid;
  place-items:center;background:var(--sunken);color:var(--muted)}
.ifield:focus-within .fico{background:var(--accent-soft);color:var(--accent)}
.ftext{flex:1;min-width:0}
.ftext > span{display:block;color:var(--muted);font:400 .6875rem/1 var(--font)}
.ftext input,.ftext select{inline-size:100%;border:0;background:none;color:var(--text);
  padding:6px 0 0;font:500 .9375rem/1.2 var(--font);-webkit-appearance:none;appearance:none}
.ftext input:focus,.ftext select:focus{outline:none}
.eye{flex:none;border:0;background:none;cursor:pointer;color:var(--muted);padding:6px}

/* password strength, shown as four segments rather than a word alone */
.pwbar{display:flex;gap:4px;margin-top:10px}
.pwbar i{flex:1;block-size:4px;border-radius:2px;background:var(--sunken);
  transition:background .2s var(--ease)}
.pwbar i.on{background:var(--accent)}
.pwbar i.weak{background:var(--danger)}
.pwhint{margin-top:8px;color:var(--muted);font:400 .75rem/1.4 var(--font)}
.pwhint b{color:var(--text);font-weight:600}
.forgot{display:block;margin-top:14px;text-align:center;border:0;background:none;
  cursor:pointer;color:var(--accent);font:500 .8125rem/1 var(--font);width:100%}

/* ---- progress ----
   A slim bar and a plain count, rather than numbered circles joined by fat
   connectors: the connectors read as empty input fields at a glance, and the
   labels stop fitting the moment the language changes. */
.stepnote{margin:20px 0 10px;color:var(--muted);font:500 .75rem/1 var(--font);
  letter-spacing:.02em}
.stepbar{display:flex;gap:5px;margin-bottom:22px}
.stepbar i{flex:1;block-size:3px;border-radius:3px;background:var(--sunken);
  transition:background .3s var(--ease)}
.stepbar i.on{background:var(--accent)}
.sustep{display:none}
.sustep.on{display:block}
/* Consent rows are separate, because agreeing to terms is not the same act as
   agreeing to how your data is handled. */
.consents{display:grid;gap:12px;margin-top:20px}
.consents .consent{margin-top:0;align-items:flex-start}
.optional{color:var(--muted);font-weight:400}

.rulecard{display:flex;gap:14px;align-items:flex-start;background:var(--surface);
  border-radius:var(--r-l);padding:16px;box-shadow:var(--lift);margin-top:10px}
.rulecard .ruleico{inline-size:38px;block-size:38px;border-radius:12px;flex:none;
  display:grid;place-items:center;background:var(--sunken);color:var(--muted)}
.rulecard b{display:block;font:600 .9375rem/1.3 var(--font);letter-spacing:-.02em}
.rulecard p{margin:6px 0 0;color:var(--muted);font:400 .8125rem/1.55 var(--font)}

/* ---- terms ---- */
.terms h3{margin:24px 0 8px;font:600 .9375rem/1.3 var(--font);letter-spacing:-.02em}
.terms h3:first-of-type{margin-top:16px}
.terms p{margin:0 0 10px;color:var(--muted);font:400 .875rem/1.55 var(--font)}
.terms p b{color:var(--text);font-weight:600}
.terms .updated{margin-top:6px;color:var(--muted);font:400 .75rem/1 var(--font)}

/* ---- collapsible pass ----
   Bids live inside the listing they are for, so you open a pass and see exactly
   who is asking. A pass with someone waiting opens by itself. */
.owned{padding:0;overflow:hidden}
.ohead{display:flex;align-items:center;gap:9px;width:100%;border:0;background:none;
  cursor:pointer;font:inherit;color:inherit;text-align:left;padding:16px}
.ohead .logo{inline-size:34px;block-size:34px;border-radius:11px;font-size:.6875rem}
.ohead-t{flex:1;min-width:0}
.ohead-t b{display:block;font:600 .9375rem/1 var(--font);letter-spacing:-.02em}
.ohead-t span{display:block;margin-top:4px;color:var(--muted);font:400 .75rem/1 var(--font)}
.chev{flex:none;color:var(--muted);transition:transform .25s var(--ease)}
.ohead[aria-expanded="true"] .chev{transform:rotate(90deg)}
.obody{padding:0 16px 16px}
.obody[hidden]{display:none}

/* ---- bids inside a pass ---- */
.bids{margin-top:14px;border-top:1px solid var(--hair);padding-top:6px}
.bids-h{display:flex;align-items:baseline;justify-content:space-between;margin-top:8px}
.bids-h b{font:600 .8125rem/1 var(--font)}
.bids-h span{color:var(--muted);font:400 .6875rem/1 var(--font)}
.bid{display:flex;gap:11px;align-items:flex-start;padding:12px 0;
  border-top:1px solid var(--hair)}
.bid:nth-of-type(1){border-top:0}
.bidt{flex:1;min-width:0}
.bidt b{font:600 .8125rem/1 var(--font)}
.bidt p{margin:6px 0 0;color:var(--muted);font:400 .75rem/1.4 var(--font)}
.bidt .amt{color:var(--text);font-weight:600;font-variant-numeric:tabular-nums}
.bidt .under{color:var(--warning)}
.bidt .over{color:var(--success)}

/* ---- profile photo ---- */
.avatar-edit{position:relative;flex:none;border:0;background:none;padding:0;cursor:pointer;
  border-radius:var(--r-full);line-height:0}
.avatar-edit .face{inline-size:56px;block-size:56px;font-size:1.0625rem;overflow:hidden}
.face img{inline-size:100%;block-size:100%;object-fit:cover;display:block}
.avatar-cam{position:absolute;right:-2px;bottom:-2px;inline-size:24px;block-size:24px;
  border-radius:var(--r-full);display:grid;place-items:center;background:var(--accent);
  color:var(--on-accent);box-shadow:0 0 0 2.5px var(--bg)}
.avatar-edit:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
.avatar-actions{display:flex;gap:8px;margin-top:12px}
.avatar-actions button{border:1px solid var(--hair);background:var(--surface);
  color:var(--text);cursor:pointer;border-radius:var(--r-full);padding:10px 14px;
  font:500 .8125rem/1 var(--font)}
.avatar-actions button.danger{color:var(--danger);border-color:var(--hair)}
.avatar-err{margin-top:10px;color:var(--danger);font:500 .75rem/1.4 var(--font)}

/* ---- profile ---- */
.givel{margin:14px 2px 0;color:var(--muted);font:400 .8125rem/1.5 var(--font)}
.givel b{color:var(--text);font:600 .9375rem/1 var(--font)}
.sechead{display:flex;align-items:baseline;justify-content:space-between;gap:12px}
.sechead{margin-top:28px}
.sechead .seclabel{margin:0 0 12px}
.morelink{border:0;background:none;padding:0;cursor:pointer;color:var(--accent);
  font:500 .8125rem/1 var(--font)}

/* ---- profile stats ---- */
/* Three columns so the smaller figures fill their row exactly — at 1fr 1fr the
   third tile was left sitting alone. */
.pstats{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:12px}
.pstat{background:var(--surface);border-radius:var(--r-l);padding:14px 12px;
  box-shadow:var(--lift)}
.pstat .v{font-size:1.3125rem}
/* The money saved is the one figure worth the accent — it is what taking a
   spare punch is actually worth to you. */
.pstat.saved{grid-column:1 / -1;background:var(--accent);color:var(--on-accent);
  padding:16px 16px}
.pstat.saved .v{font-size:1.9375rem}
.pstat.saved .k{color:var(--on-accent);opacity:.85}
.pstat .v{font:600 1.5rem/1 var(--font);letter-spacing:-.04em;font-variant-numeric:tabular-nums}
.pstat .k{display:block;margin-top:8px;color:var(--muted);font:400 .6875rem/1.3 var(--font)}

/* ---- where you climb ----
   Single series, so one hue and no legend: the bar length is the comparison and
   the count sits at the end of it. */
.rank{background:var(--surface);border-radius:var(--r-l);padding:16px 18px;box-shadow:var(--lift);
  display:grid;gap:13px}
.rankrow{display:flex;align-items:center;gap:11px}
.rankrow .logo{inline-size:28px;block-size:28px;border-radius:9px;font-size:.625rem}
.rankt{flex:1;min-width:0}
.rankt b{display:block;font:500 .8125rem/1 var(--font);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.rankbar{margin-top:8px;block-size:7px;border-radius:var(--r-full);background:var(--sunken);
  overflow:hidden}
.rankbar i{display:block;block-size:100%;border-radius:var(--r-full);background:var(--accent)}
.rankrow em{font-style:normal;color:var(--muted);font:500 .75rem/1 var(--font);
  font-variant-numeric:tabular-nums;flex:none}
.rankrow:first-child .rankbar i{background:var(--accent)}
.rankrow:not(:first-child) .rankbar i{background:var(--border-strong)}

/* ---- history ---- */
.histfilter{display:flex;gap:4px;padding:4px;background:var(--sunken);
  border-radius:var(--r-full);margin-bottom:10px}
.histfilter button{flex:1;border:0;background:none;cursor:pointer;border-radius:var(--r-full);
  padding:10px 6px;font:500 .75rem/1 var(--font);color:var(--muted)}
.histfilter button[aria-pressed="true"]{background:var(--surface);color:var(--text);
  box-shadow:0 1px 2px rgb(28 15 43/.07)}
.hist{background:var(--surface);border-radius:var(--r-l);padding:4px 18px;box-shadow:var(--lift)}
.histrow{display:flex;align-items:center;gap:12px;padding:14px 0;
  border-top:1px solid var(--hair)}
.histrow:first-child{border-top:0}
.histrow .logo{inline-size:30px;block-size:30px;margin-block:-4px;border-radius:10px;font-size:.6875rem}
.histt{flex:1;min-width:0}
.histt b{display:block;font:500 .875rem/1 var(--font)}
.histt span{display:block;margin-top:4px;color:var(--muted);font:400 .75rem/1 var(--font)}
.histside{text-align:right;flex:none}
.histside .tag2{display:inline-block;border-radius:var(--r-full);padding:4px 10px;
  font:500 .625rem/1 var(--font);background:var(--accent-soft);color:var(--accent)}
.histside .tag2.in{background:var(--sunken);color:var(--muted)}
.histside .amt{display:block;margin-top:6px;color:var(--muted);font:400 .6875rem/1 var(--font);
  font-variant-numeric:tabular-nums}
.savedbit{display:block;margin-top:4px;color:var(--success);font-weight:500}

  .langswitch{margin-left:auto;flex:none;padding:4px}
  .langswitch button{padding:8px 14px;font-size:.8125rem;flex:none}

/* ---- settings rows ----
   An icon per row: the list is scanned for one setting, not read top to bottom. */
.irow-ico{inline-size:30px;block-size:30px;border-radius:9px;flex:none;display:grid;
  place-items:center;background:var(--sunken);color:var(--muted);margin-right:12px}
.item.asrow .irow-ico,.list .item .irow-ico{margin-right:12px}

  .langswitch{margin-left:auto;flex:none;padding:4px}
  .langswitch button{padding:8px 14px;font-size:.8125rem;flex:none}

/* ---- settings rows ---- */
.rowlink{display:flex;align-items:center;justify-content:space-between;width:100%;
  margin-top:10px;border:0;cursor:pointer;background:var(--surface);color:var(--text);
  border-radius:var(--r-l);padding:16px 18px;box-shadow:var(--lift);
  font:500 .9375rem/1 var(--font);letter-spacing:-.01em}
.rowlink.danger{color:var(--muted);justify-content:center;box-shadow:none;
  background:var(--sunken)}
.item.asrow{width:100%;border:0;background:none;cursor:pointer;font:inherit;color:inherit}
.item.asrow svg{color:var(--muted)}
/* Toggle built from the checkbox itself, so it keeps real keyboard and
   screen-reader behaviour instead of being a styled div. */
.tg{appearance:none;-webkit-appearance:none;margin:0 0 0 auto;inline-size:46px;
  block-size:28px;border-radius:var(--r-full);background:var(--sunken);position:relative;
  cursor:pointer;flex:none;transition:background .2s var(--ease)}
.tg::after{content:"";position:absolute;top:3px;left:3px;inline-size:22px;block-size:22px;
  border-radius:50%;background:var(--surface);box-shadow:0 1px 3px rgb(28 15 43/.25);
  transition:transform .2s var(--ease)}
.tg:checked{background:var(--accent)}
.tg:checked::after{transform:translateX(18px)}
.tg:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
label.item{cursor:pointer}

/* ---- app footer ---- */
.appfoot{margin:28px 2px 0;text-align:center;color:var(--muted);
  font:400 .75rem/1.5 var(--font);text-wrap:balance}
.appfoot p{margin:0 0 6px}
.appfoot b{color:var(--text);font-weight:600}
.linkish{border:0;background:none;padding:0;cursor:pointer;color:var(--accent);
  font:inherit;font-weight:500;text-decoration:underline}
.appfoot .ver{color:var(--muted)}

/* ---- liquid glass nav ----
   Tint opacity is a contrast floor, not taste: worst-cased against solid black
   and white content beneath, light needs >=.51 and dark >=.71.
   It rides large, then condenses as you scroll down and returns on scroll up. */
/* ---- the bar ----
   Four fixed destinations, docked to the bottom edge on a white ground with a
   hairline above it. It does not float, condense or slide: the deck draws a
   plain bar, and a plain bar is also one fewer thing to keep in step. */
.nav{position:fixed;inset-inline:0;bottom:0;z-index:50;background:var(--surface);
  border-top:1px solid var(--hair);padding-bottom:env(safe-area-inset-bottom,0px)}
.bar{display:grid;grid-template-columns:repeat(4,1fr);max-inline-size:34rem;margin-inline:auto}
.tab{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  border:0;background:none;cursor:pointer;color:var(--muted);padding:10px 4px 12px;
  min-block-size:58px;font:inherit}
.tab svg{inline-size:22px;block-size:22px;flex:none}
.tab .lbl{font:500 .6875rem/1 var(--font);letter-spacing:-.01em}
.tab[aria-current="page"]{color:var(--text)}
.tab[aria-current="page"] .lbl{font-weight:600}
.tab#fab{color:var(--hot-text)}
/* ==========================================================================
   ONE COLUMN, EVERY WIDTH
   Last in the sheet on purpose. The desktop rules above are still here and
   still correct for the shell they describe; these switch that shell off
   rather than editing it in twenty places, and a media query adds no
   specificity, so only source order can win.
   ========================================================================== */
.topbar{display:none}
.deskside{display:none}
.rail-empty{display:none!important}

/* ==========================================================================
   DESKTOP, 960px AND UP
   The board becomes a grid under a top bar; anything you read stays a
   column. Last in the sheet on purpose: media queries add no specificity, so
   only source order lets this win over the phone rules above.
   ========================================================================== */
@media (min-width:760px){
  .topbar{display:block;position:sticky;top:0;z-index:40;
    background:var(--surface);border-bottom:1px solid var(--hair);
    box-shadow:0 1px 2px rgb(28 15 43/.04)}
  body.auth .topbar{display:none}
  .tb-in{max-inline-size:76rem;margin-inline:auto;padding:0 24px;block-size:64px;
    display:flex;align-items:center;gap:16px}
  .tb-brand{display:flex;align-items:center;gap:8px;flex:none;border:0;background:none;
    cursor:pointer;color:var(--text);padding:6px 4px;font:600 1.125rem/1 var(--font);letter-spacing:-.03em}
  .tb-brand .logomark{font-size:1.625rem}
  .tb-seg{display:flex;gap:2px;padding:4px;flex:none;background:var(--sunken);border-radius:var(--r-full)}
  .tb-seg button{border:0;background:none;cursor:pointer;border-radius:var(--r-full);
    padding:9px 14px;font:500 .8125rem/1 var(--font);color:var(--muted);white-space:nowrap}
  .tb-seg button[aria-pressed="true"]{background:var(--surface);color:var(--text);
    box-shadow:0 1px 2px rgb(28 15 43/.08)}
  .tb-search{flex:1;min-width:0;display:flex;align-items:center;gap:8px;block-size:40px;
    padding:0 14px;background:var(--sunken);border-radius:var(--r-full);color:var(--muted)}
  .tb-search:focus-within{box-shadow:0 0 0 2px var(--focus)}
  .tb-search input{flex:1;min-width:0;border:0;background:none;outline:none;
    font:400 .875rem/1 var(--font);color:var(--text)}
  .tb-end{display:flex;align-items:center;gap:8px;flex:none}
  .tb-icon{position:relative;inline-size:40px;block-size:40px;display:grid;place-items:center;
    border:0;background:none;cursor:pointer;border-radius:var(--r-full);color:var(--text)}
  .tb-icon:hover{background:var(--sunken)}
  .tb-icon svg{inline-size:20px;block-size:20px}
  .tb-icon .dot{position:absolute;top:3px;right:1px;min-inline-size:17px;block-size:17px;padding:0 4px;
    border-radius:var(--r-full);background:var(--danger);color:var(--on-accent);
    font:600 .625rem/17px var(--font);text-align:center;box-shadow:0 0 0 2px var(--surface)}
  .tb-signin{border:1px solid var(--hair);background:var(--surface);cursor:pointer;color:var(--text);
    border-radius:var(--r-full);padding:11px 16px;font:600 .8125rem/1 var(--font)}
  .tb-me{display:flex;align-items:center;gap:8px;border:0;background:none;cursor:pointer;
    border-radius:var(--r-full);padding:4px 12px 4px 4px;font:500 .8125rem/1 var(--font);color:var(--text);
    max-inline-size:14rem}
  .tb-me span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .tb-me:hover,.tb-me[aria-current="true"]{background:var(--sunken)}
  .tb-me .face{inline-size:30px;block-size:30px;margin-block:-4px;font-size:.6875rem}
  .tb-post{display:flex;align-items:center;gap:6px;border:0;cursor:pointer;white-space:nowrap;
    background:var(--accent);color:var(--on-accent);border-radius:var(--r-full);
    padding:11px 16px;font:600 .8125rem/1 var(--font)}
  .tb-post:hover{filter:brightness(1.08)}

  /* The phone chrome the bar replaces. */
  .nav{display:none}
  /* The plum band and the side switch move into the bar at this width. The
     band is one element now, so hide that rather than its parts. */
  .feedhead,#seg{display:none}

  /* The board is wide; anything you read is a column. */
  .shell{max-inline-size:76rem;padding-bottom:64px}
  .shell > .screen:not(#feed){max-inline-size:40rem;margin-inline:auto}
  .shell > .screen#signin,.shell > .screen#signup,.shell > .screen#onboard{max-inline-size:28rem}

  /* The board as a grid: 2 across on a laptop, 3 on a wide screen. */
  #cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(20rem,1fr));gap:16px}
  #cards > .card{margin-top:0;display:flex;flex-direction:column}
  #cards > .card .vs,#cards > .card .setbadge{align-self:flex-start}
  #cards > .card .cardacts{margin-top:auto}
  #cards > .empty{grid-column:1/-1}

  /* Sheets become dialogs in the middle of the screen, not drawers from the bottom. */
  .sheet{align-items:center}
  .toast{bottom:32px}

  /* The page ends with the footer, even when a screen is short: the body is a
     column and the content takes whatever height is left. */
  body{display:flex;flex-direction:column;min-block-size:100dvh}
  .shell{flex:1 0 auto;inline-size:100%;min-block-size:0}
  .appfoot{display:none}

  .sitefoot{display:block;background:var(--surface);border-top:1px solid var(--hair)}
  body.auth .sitefoot{display:none}
  .sf-in{max-inline-size:76rem;margin-inline:auto;padding:44px 24px 36px;
    display:grid;grid-template-columns:minmax(0,1.7fr) repeat(3,minmax(0,1fr));gap:40px}
  .sf-logo{display:flex;align-items:center;gap:8px;color:var(--text);
    font:600 1.125rem/1 var(--font);letter-spacing:-.03em}
  .sf-logo .logomark{font-size:1.625rem}
  .sf-tag{margin:14px 0 0;font:500 .875rem/1.5 var(--font);color:var(--text)}
  .sf-say{margin:8px 0 0;max-inline-size:34ch;font:400 .8125rem/1.6 var(--font);color:var(--muted)}
  .sf-col{display:flex;flex-direction:column;align-items:flex-start;gap:12px}
  .sf-col h4{margin:0 0 2px;font:600 .6875rem/1 var(--font);letter-spacing:.07em;
    text-transform:uppercase;color:var(--muted)}
  .sf-col button,.sf-col a{border:0;background:none;padding:0;cursor:pointer;text-align:left;
    color:var(--text);text-decoration:none;font:400 .8125rem/1.3 var(--font)}
  .sf-col button:hover,.sf-col a:hover{color:var(--accent)}
  .sf-bottom{max-inline-size:76rem;margin-inline:auto;padding:16px 24px 28px;
    border-top:1px solid var(--hair);display:flex;justify-content:space-between;gap:16px;
    color:var(--muted);font:400 .75rem/1.4 var(--font)}
}

/* ---- picker ----
   A date or a time is chosen on a sheet made from the same parts as every
   other sheet here — the surface, the radius, the teal, the chips — so the one
   control that used to belong to the operating system now belongs to Spare. */
.pickbtn{display:flex;align-items:center;justify-content:space-between;gap:10px;
  inline-size:100%;border:0;background:none;padding:6px 0 0;cursor:pointer;
  color:var(--text);font:500 1rem/1.2 var(--font);text-align:start}
.ftext .pickbtn{font-size:.9375rem}
.pickbtn b{font:inherit;min-inline-size:0}
.pickbtn.empty b{color:var(--muted);font-weight:400}
.pickbtn svg{flex:none;color:var(--muted)}
.pk-sheet{overscroll-behavior:contain}
.pk{max-width:22.5rem;padding:18px 18px 14px}
.pk-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:6px}
.pk-head h2{font-size:1.0625rem}
.pk-x{display:grid;place-items:center;inline-size:34px;block-size:34px;border:0;
  border-radius:var(--r-full);background:var(--sunken);color:var(--muted);cursor:pointer}
.pk-x:hover{color:var(--text)}
.pk-nav{display:grid;grid-template-columns:44px 1fr 44px;align-items:center;margin:6px 0 8px}
.pk-arrow{display:grid;place-items:center;inline-size:44px;block-size:44px;border:0;
  background:none;border-radius:var(--r-full);color:var(--text);cursor:pointer}
.pk-arrow:hover:not(:disabled){background:var(--sunken)}
.pk-arrow:disabled{color:var(--muted);opacity:.35;cursor:default}
.pk-month{justify-self:center;display:inline-flex;align-items:center;gap:6px;border:0;
  background:none;cursor:pointer;color:var(--text);border-radius:var(--r-full);
  padding:9px 14px;font:600 .9375rem/1 var(--font);letter-spacing:-.015em}
.pk-month b{font:inherit}
.pk-month:hover{background:var(--sunken)}
.pk-month svg{transition:transform .18s var(--ease)}
.pk-month[aria-expanded="true"] svg{transform:rotate(180deg)}
.pk-dow,.pk-days{display:grid;grid-template-columns:repeat(7,1fr)}
.pk-dow span{text-align:center;color:var(--muted);font:500 .6875rem/1 var(--font);padding:6px 0 8px}
.pk-day{display:grid;place-items:center;aspect-ratio:1;max-block-size:44px;margin:1px;
  border:0;background:none;cursor:pointer;border-radius:var(--r-full);color:var(--text);
  font:500 .875rem/1 var(--font);font-variant-numeric:tabular-nums}
.pk-day:hover:not(:disabled){background:var(--sunken)}
.pk-day.today{box-shadow:inset 0 0 0 1.5px var(--accent)}
.pk-day[aria-pressed="true"]{background:var(--accent);color:var(--on-accent);font-weight:600;box-shadow:none}
.pk-day:disabled{color:var(--muted);opacity:.35;cursor:default}
.pk-years{display:grid;grid-template-columns:repeat(4,1fr);gap:4px;max-block-size:16.5rem;
  overflow-y:auto;overscroll-behavior:contain;padding:2px;margin-top:4px}
.pk-years button{border:0;background:none;cursor:pointer;border-radius:var(--r-full);
  padding:11px 0;color:var(--text);font:500 .875rem/1 var(--font);font-variant-numeric:tabular-nums}
.pk-years button:hover{background:var(--sunken)}
.pk-years button[aria-pressed="true"]{background:var(--accent);color:var(--on-accent);font-weight:600}
.pk-presets{margin-top:10px}
.pk-hint{margin:10px 2px 0;color:var(--muted);font:400 .75rem/1.45 var(--font)}
.pk-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:10px;padding-top:6px}
.pk-link{border:0;background:none;cursor:pointer;color:var(--accent);padding:10px 4px;font:600 .875rem/1 var(--font)}
.pk-foot .pk-link:last-child,.pk-foot-time .pk-link{color:var(--muted)}
.pk-foot-time .btn{margin:0;inline-size:auto;padding:13px 26px}
.pk-readout{display:flex;align-items:baseline;gap:10px;margin:8px 0 2px}
.pk-readout b{font:600 2.25rem/1 var(--font);letter-spacing:-.04em;font-variant-numeric:tabular-nums}
.pk-readout span{color:var(--muted);font:400 .875rem/1 var(--font)}
.pk-when{margin:6px 0 0;color:var(--muted);font:400 .8125rem/1.4 var(--font)}
.pk-when button{border:0;background:none;padding:0;margin-inline-start:6px;cursor:pointer;
  color:var(--accent);font:inherit;font-weight:600}
.pk-lab{margin:16px 0 8px;color:var(--muted);font:500 .6875rem/1 var(--font);
  letter-spacing:.04em;text-transform:uppercase}
.pk-grid{display:grid;gap:6px}
.pk-hours{grid-template-columns:repeat(6,1fr)}
.pk-mins{grid-template-columns:repeat(4,1fr)}
.pk-grid button{border:1px solid var(--hair);background:var(--surface);color:var(--text);
  border-radius:var(--r-full);padding:10px 0;cursor:pointer;font:500 .875rem/1 var(--font);
  font-variant-numeric:tabular-nums}
.pk-grid button:hover:not(:disabled){border-color:var(--accent)}
.pk-grid button[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);
  color:var(--on-accent);font-weight:600}
.pk-grid button:disabled{color:var(--muted);opacity:.35;cursor:default}

/* ---- stepper field ----
   A count or a price is a number somebody chooses, and the buttons are what
   they reach for. The box between them is read-only on purpose: a typed
   "3.5 passes" or "฿ten" has to be validated, a tapped one cannot be wrong. */
.stepfield{display:flex;align-items:center;gap:8px;margin-top:6px}
.field .stepfield input,.stepfield input{flex:1 1 0;min-inline-size:0;inline-size:0;padding:0;
  text-align:center;cursor:default;font:600 1.25rem/1 var(--font);letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;-moz-appearance:textfield}
.stepfield input::-webkit-outer-spin-button,.stepfield input::-webkit-inner-spin-button{
  -webkit-appearance:none;margin:0}
.stepfield input:focus{outline:none}
.stepfield button{display:grid;place-items:center;flex:none;inline-size:44px;block-size:44px;
  border:0;border-radius:var(--r-full);background:var(--sunken);color:var(--text);
  cursor:pointer;font:600 1.25rem/1 var(--font);touch-action:manipulation;user-select:none}
.stepfield button:hover:not(:disabled){background:var(--accent-soft);color:var(--accent)}
.stepfield button:disabled{color:var(--muted);opacity:.4;cursor:default}
.offerbox .stepfield button{background:var(--surface)}
/* Passes and price are two steppers; side by side they need about 15rem each,
   which a phone does not have. Stacked is two full-width controls, which is
   what a thumb wants anyway. The grid tracks are minmax(0,…) because a track
   sized to its content would otherwise grow to the input's default width. */
#wrap-row{grid-template-columns:minmax(0,1fr)}
@media (min-width:32rem){#wrap-row{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
@media (max-width:26rem){.stepfield input{font-size:1.0625rem}}
.offerrow{align-items:flex-end}
.offerpart{flex:1;min-width:0}
.offerpart.narrow{flex:none}
.offerpart>span{display:block;color:var(--muted);font:400 .6875rem/1 var(--font)}
.offerpart>span em{font-style:normal;color:var(--muted);font-weight:400}
.offerpart .stepfield{margin-top:8px}
.offerpart .stepper{margin-top:8px}

/* ---- quick replies ----
   Most of what two people say to arrange a handover is one of about six
   sentences. They are one tap; the box stays for everything else. */
.quick{margin:12px 0 0}
.quick button{padding:9px 13px;font-size:.8125rem;color:var(--text)}
.quick .quick-when{color:var(--accent);border-color:var(--accent)}

/* A [hidden] attribute loses to any rule that sets display, so say it. */
.problem[hidden]{display:none}
.ifield.invalid{border-color:var(--danger)}
.ifield.invalid .ftext>span{color:var(--danger)}

/* ---- back, on desktop ----
   On a phone the back link is a small grey label at the edge of a narrow
   column, which is fine under a thumb. On a wider screen it is easy to lose and
   gives no sign that it is a control. Here it is a real button: a surface with
   an edge, ink instead of grey, a hover that says it will move you, and an
   arrow that leans the way you are going. */
@media (min-width:760px){
  .back{margin:22px 0 18px;padding:9px 18px 9px 12px;gap:8px;color:var(--text);
    background:var(--surface);border-radius:var(--r-full);
    box-shadow:0 0 0 1px var(--hair),0 1px 2px rgb(28 15 43/.04);
    font:600 .875rem/1 var(--font);
    transition:box-shadow .18s var(--ease),color .18s var(--ease),transform .18s var(--ease)}
  .back svg{inline-size:16px;block-size:16px;flex:none;
    transition:transform .18s var(--ease)}
  .back:hover{color:var(--accent);box-shadow:0 0 0 1px var(--accent),var(--lift)}
  .back:hover svg{transform:translateX(-3px)}
  .back:active{transform:scale(.98)}
}

/* Named for screen readers, invisible on screen. */
.sr-only{position:absolute;inline-size:1px;block-size:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* After sign-up there is no headline or form, so the logo no longer needs the
   whole height: the logo, the thank-you and the footer sit together, centred. */
/* The column is centred as one block, so the space a tall window has to spare
   goes above and below it rather than into a gap in the middle. */
.comingsoon{justify-content:center}
.comingsoon .soon-mid{flex:none;padding-bottom:36px}
.comingsoon .soon-legal{margin-top:auto}
.comingsoon .soon-mid{margin-top:auto}
.comingsoon.done .soon-done{padding-bottom:28px}

/* ---- not the live site ----
   A staging build wears a label. Small, fixed and out of the way, but never
   absent: the whole risk of a staging copy is forgetting which one you are
   looking at. */
.envmark{position:fixed;z-index:200;inset-block-start:0;inset-inline-start:0;
  padding:4px 10px 5px;border-end-end-radius:var(--r-s);
  background:var(--hot);color:var(--on-hot);pointer-events:none;
  font:700 .625rem/1 'DM Mono',ui-monospace,monospace;letter-spacing:.14em}
@media (min-width:760px){.envmark{inset-block-start:auto;inset-block-end:0;
  border-radius:0 var(--r-s) 0 0}}

/* ---- the pass card, redesigned ---- */
.card2{padding:20px;border-radius:20px;display:flex;flex-direction:column;gap:14px;margin-top:12px}
.c2-top{display:flex;align-items:center;gap:12px}
.c2-top .logo,.c2-top .logo.brand{inline-size:38px;block-size:38px;border-radius:0;background:none}
.c2-top .logo img{inline-size:100%;block-size:100%}
.c2-title{flex:1 1 auto;min-width:0}
.c2-title h3{margin:0;font-size:1.1875rem;font-weight:700;letter-spacing:-.015em;line-height:1.2;text-wrap:balance}
.c2-sub{display:block;margin-top:5px;color:var(--muted);font:400 .9375rem/1.2 var(--font)}
.card2 .c2-save,.card2 .c2-save:hover,.card2 .c2-save.on{background:none;border-radius:0}
.card2 .c2-save{flex:none;padding:6px 0 6px 8px;font-size:.875rem;font-weight:500;color:var(--muted)}
.card2 .c2-save:hover{color:var(--text)}
.card2 .c2-save.on{color:var(--accent);font-weight:600}
.c2-tags{display:flex;flex-wrap:wrap;gap:8px}
.card2 .tag{display:inline-flex;align-items:center;padding:7px 13px;border-radius:999px;background:var(--sunken);
  color:var(--text);font:500 .8125rem/1.2 var(--font)}
.card2 .tag.kind{background:var(--accent-soft);color:var(--accent);font-weight:600}
.card2 .vs,.card2 .vs.bad{margin-top:0;padding:0;border-radius:0;background:none;
  font-size:.8125rem;font-weight:400;color:var(--muted)}
.card2 .vs.bad{color:var(--warning)}
.card2 .vs .unconfirmed{margin-inline-start:6px;padding:0;background:none;border:0;color:var(--muted);
  font-size:.75rem;font-style:italic}
.c2-foot{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;
  padding-top:16px;border-top:1px solid var(--hair);margin-top:auto}
.c2-price{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.c2-price b{font:700 1.5rem/1 var(--font);letter-spacing:-.02em}
.c2-price b.free{color:var(--ok,#177453)}
.c2-price s{color:var(--muted);font:400 1rem/1 var(--font)}
.c2-price small{color:var(--muted);font:400 .8125rem/1 var(--font)}
.c2-meta{display:flex;flex-direction:column;align-items:flex-end;gap:5px;text-align:end;
  color:var(--muted);font:400 .875rem/1.2 var(--font)}
.c2-meta .who{color:var(--muted)}
.c2-meta .daysleft{font-size:.8125rem}

/* ---- the listing page, plainer: no tiles, pills or boxes ----
   The same treatment as the card on the board. Facts sit on the page with a
   hairline between them; the only things that keep a shape are the controls. */
#detail .d-mark .logo,#detail .d-mark .logo.brand{inline-size:38px;block-size:38px;border-radius:0;
  background:none;box-shadow:none}
#detail .d-mark .logo img{padding:0}
#detail .d-head h1{font-size:1.5rem;letter-spacing:-.02em;line-height:1.15}
#detail .d-actions{display:flex;flex-wrap:wrap;gap:20px;margin-top:10px}
#detail .d-share,#detail .d-share:hover{border:0;background:none;border-radius:0;box-shadow:none;
  padding:6px 0;color:var(--muted);font:500 .875rem/1 var(--font)}
#detail .d-share:hover{color:var(--text)}
#detail .d-save[aria-pressed="true"]{color:var(--accent);font-weight:600}
#detail .grid2{grid-template-columns:1fr;gap:12px;margin-top:16px!important;padding:0;border:0}
#detail .stat{background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-m);padding:16px 18px}
#detail .stat .v{font-size:1.375rem;letter-spacing:-.02em}
#detail #d-vs .vs,#detail #d-vs .vs.bad{margin-top:14px;padding:0;border-radius:0;background:none;
  font-size:.875rem;font-weight:400;color:var(--muted)}
#detail #d-vs .vs.bad{color:var(--warning)}
#detail #d-vs .unconfirmed{margin-inline-start:6px;padding:0;background:none;color:var(--muted);
  font-size:.75rem;font-style:italic}
#detail .offerbox{margin-top:18px;padding:18px;border:1px solid var(--hair);border-radius:var(--r-m);background:var(--surface)}
#detail .offerhead{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 10px;
  margin-bottom:16px;padding-bottom:14px;border-bottom:1px solid var(--hair)}
#detail .offerhead .k{color:var(--muted);font:500 .8125rem/1.2 var(--font)}
#detail .offerhead .v{font:700 1.25rem/1 var(--font);letter-spacing:-.02em}
#detail .offerhead .gone{color:var(--muted);font:500 .8125rem/1.2 var(--font)}
#detail .offerhead .gone.moving{color:var(--accent);font-weight:600}
/* White box, so the controls take the grey the box used to be. */
#detail .offerbox .stepfield button,#detail .offerbox .stepper{background:var(--sunken)}
#detail .offerbox .picksug button,#detail .offerbox .picksug .chip{background:var(--sunken);border-color:transparent}
#detail .mybid{padding:12px 0;border-radius:0;background:none;border-top:1px solid var(--hair)}
#detail .seller{margin-top:22px;padding:20px 0 0;border-radius:0;background:none;box-shadow:none;
  border-top:1px solid var(--hair)}
#detail .seller-stat{padding:0;border-radius:0;background:none}
#detail .notice{margin:10px 0 14px;display:flex;gap:12px;align-items:flex-start;border-radius:0;
  background:none;box-shadow:none;overflow:visible}
#detail .notice-stub{inline-size:auto;background:none;color:var(--danger);padding-top:2px}
#detail .notice-stub::after{display:none}
#detail .notice-body{padding:0;background:none}
#detail .empty{padding:0;border-radius:0;background:none}

/* ---- the offer box, as rows ----
   Passes on one line; the offer with its asking price opposite the label and a
   large amount between its own − and +; the quick amounts; and the total set
   apart underneath, since it is what the person is actually agreeing to. */
#detail .offerrow{flex-direction:column;align-items:stretch;gap:20px}
#detail .offerpart.narrow{order:-1;display:flex;align-items:center;justify-content:space-between}
#detail .offerpart>span{display:flex;align-items:baseline;gap:8px;color:var(--text);
  font:500 .9375rem/1.2 var(--font)}
#detail .offerpart:not(.narrow)>span em{margin-inline-start:auto;color:var(--muted);
  font:400 .8125rem/1.2 var(--font)}
#detail .offerbox .stepfield{margin-top:12px;gap:12px;justify-content:space-between}
#detail .offerbox .stepfield button{inline-size:48px;block-size:48px}
#detail .offerbox .stepfield input{flex:1;min-inline-size:0;text-align:center;
  font:700 2rem/1 var(--font);letter-spacing:-.03em;padding:0}
#detail .offerbox .stepper{padding:3px}
#detail #offersug{margin-top:14px}
#detail .askline{margin-top:16px;padding-top:14px;border-top:1px solid var(--hair);
  font-size:.875rem;line-height:1.45}
#detail .askline b{font-size:1.25rem;letter-spacing:-.02em}

/* The listing dates share the passes-left row, pushed to its far side. */
#detail .offerhead .listed{margin:0 0 0 auto;font-size:.8125rem;align-items:center}
#detail .offerhead .listed svg{margin-top:0}

/* The − and + on the offer are plum, so they read as the controls. */
#detail .offerbox .stepfield button,#detail .offerbox .stepper button{
  background:var(--accent);color:var(--on-accent)}
#detail .offerbox .stepfield button:hover,#detail .offerbox .stepper button:hover:not(:disabled){
  background:var(--plum-raised,var(--accent))}
#detail .offerbox .stepper button:disabled{background:var(--accent);color:var(--on-accent);opacity:.35}
#detail .offerbox .stepper{padding:3px;gap:6px}

/* The payment note sits between the offer's title and its amount. */
#detail .offerbox .offline{margin:10px 0 0}
#detail .offerbox .offline span{display:inline;color:inherit;font:inherit}

/* Just a line of text: no icon, no box. */
#detail .offerbox .offline{display:block;margin:6px 0 0;color:var(--muted);font:400 .8125rem/1.45 var(--font)}

/* "Passes" with its question underneath. */
#detail .offerpart.narrow>.qtytxt{display:grid;gap:3px}
#detail .qtytxt #qty-lbl{display:block;color:var(--text);font:500 .9375rem/1.2 var(--font)}
#detail .qtytxt small{color:var(--muted);font:400 .8125rem/1.3 var(--font)}
/* The total and the day-pass comparison share the box's last row. */
#detail .askrow{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;
  gap:6px 16px;margin-top:16px;padding-top:14px;border-top:1px solid var(--hair)}
#detail .askrow .askline{margin:0;padding:0;border:0}
#detail .askrow #d-vs{white-space:nowrap}
#detail .askrow #d-vs .vs,#detail .askrow #d-vs .vs.bad{margin:0;padding:0;font-size:.8125rem;font-weight:400}

/* The lister: name and View profile on one row; the red-flag note and the
   handover count are not shown. (They are still filled in by the script, so
   they are hidden rather than removed.) */
#detail .seller-rate,#detail .seller-note{display:none}
#detail .seller-foot{display:contents}
#detail .seller-go{grid-column:3;grid-row:1;align-self:center}

/* One white box for the conversation: it holds the prompt to send a request
   now, and becomes the thread and the composer once there is one. */
#detail .msgarea{display:flex;flex-direction:column;gap:12px;min-height:130px;padding:18px;
  border:1px solid var(--hair);border-radius:var(--r-m);background:var(--surface)}
#detail .msgarea .empty{margin:0}
#detail .msgarea .composer{margin-top:auto}

/* Give side, on the Take card's frame. */
.card2 .c2-note{margin:0;color:var(--muted);font:400 .875rem/1.45 var(--font)}
.c2-top .havebtn{flex:none;margin-inline-start:auto}
.c2-top .mine,.c2-top .state{flex:none;margin-inline-start:auto}

/* The sign-in box and the sign-in page: the label sits above the field, and the icon has no tile. */
#authsheet .as-form{gap:14px}
#authsheet .as-field{display:grid;gap:6px}
#authsheet .as-lbl{margin:0;color:var(--text);font:500 .875rem/1.2 var(--font)}
#authsheet .as-field:has(.invalid) .as-lbl{color:var(--danger)}
#authsheet .as-box{gap:10px;padding:0 12px;min-block-size:50px;box-shadow:none}
#authsheet .as-box .fico,#authsheet .as-box:focus-within .fico{inline-size:20px;block-size:20px;border-radius:0;
  background:none;color:var(--muted)}
#authsheet .as-box:focus-within .fico{color:var(--accent)}
#authsheet .as-box input{flex:1;min-inline-size:0;border:0;background:none;color:var(--text);
  padding:0;font:500 1rem/1.2 var(--font)}
#authsheet .as-box input:focus{outline:none}
#authsheet .as-box .eye{padding:6px}
#authsheet .as-field .problem{margin:0}

/* Logo and title share a row in the sign-in box. */
#authsheet .as-head{display:flex;align-items:center;gap:12px}
#authsheet .as-head .sheet-logo{margin:0;flex:none}
#authsheet .as-head .sheet-logo .logomark{inline-size:36px;block-size:36px}
#authsheet .as-head h2{margin:0}

#signin .as-form{gap:14px}
#signin .as-field{display:grid;gap:6px}
#signin .as-lbl{margin:0;color:var(--text);font:500 .875rem/1.2 var(--font)}
#signin .as-field:has(.invalid) .as-lbl{color:var(--danger)}
#signin .as-box{gap:10px;padding:0 12px;min-block-size:50px;box-shadow:none}
#signin .as-box .fico,#signin .as-box:focus-within .fico{inline-size:20px;block-size:20px;border-radius:0;
  background:none;color:var(--muted)}
#signin .as-box:focus-within .fico{color:var(--accent)}
#signin .as-box input{flex:1;min-inline-size:0;border:0;background:none;color:var(--text);
  padding:0;font:500 1rem/1.2 var(--font)}
#signin .as-box input:focus{outline:none}
#signin .as-box .eye{padding:6px}
#signin .as-field .problem{margin:0}


/* ---- every form: the label above the box, and icons with no tile ----
   One look for the sign-up steps, the post and request forms and the rest. The
   box is the control itself, not a card around a label and a control. */
label.ifield{display:grid;grid-template-columns:auto 1fr auto;column-gap:10px;row-gap:6px;align-items:center;
  position:relative;margin:0;padding:0;background:none;border:0;box-shadow:none}
label.ifield .ftext{display:contents}
label.ifield .ftext>span:first-child{grid-column:1/-1;grid-row:1;color:var(--text);font:500 .875rem/1.2 var(--font)}
label.ifield::before{content:"";grid-column:1/-1;grid-row:2;align-self:stretch;min-block-size:50px;
  border:1.5px solid var(--hair);border-radius:var(--r-m);background:var(--surface);
  transition:border-color .15s var(--ease)}
label.ifield:focus-within::before{border-color:var(--accent)}
label.ifield.invalid::before{border-color:var(--danger)}
label.ifield.invalid .ftext>span:first-child{color:var(--danger)}
label.ifield .fico,label.ifield:focus-within .fico{grid-column:1;grid-row:2;z-index:1;margin-inline-start:14px;
  inline-size:20px;block-size:20px;border-radius:0;background:none;color:var(--muted)}
label.ifield:focus-within .fico{color:var(--accent)}
label.ifield .ftext>:not(:first-child){grid-column:2;grid-row:2;z-index:1;min-inline-size:0}
label.ifield .ftext input,label.ifield .ftext select{padding:0;min-block-size:48px;font:500 1rem/1.2 var(--font)}
label.ifield .ftext .pickbtn{grid-column:2/-1;padding-inline-end:14px;min-block-size:48px;font-size:1rem}
label.ifield>.eye{grid-column:3;grid-row:2;z-index:1;margin-inline-end:6px}

.field{display:grid;gap:8px;padding:0;border-radius:0;background:none;box-shadow:none}
.field>span:first-child{color:var(--text);font:500 .875rem/1.2 var(--font)}
.field>input:not([hidden]),.field>select,.field>.pickbtn{box-sizing:border-box;inline-size:100%;
  min-block-size:50px;padding:0 14px;border:1.5px solid var(--hair);border-radius:var(--r-m);background:var(--surface)}
.field>input:focus,.field>select:focus{outline:none;border-color:var(--accent)}
.field.invalid{box-shadow:none}
.field.invalid>input,.field.invalid>select,.field.invalid>.pickbtn{border-color:var(--danger)}

/* Date of birth as three dropdowns. */
.dobrow{display:grid;grid-template-columns:1fr 1.5fr 1.1fr auto;gap:10px}
.dobrow select{box-sizing:border-box;inline-size:100%;min-block-size:50px;padding:0 34px 0 14px;
  border:1.5px solid var(--hair);border-radius:var(--r-m);color:var(--text);font:500 1rem/1.2 var(--font);
  -webkit-appearance:none;appearance:none;
  background:var(--surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%235d5068' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 12px center}
.dobrow select:focus{outline:none;border-color:var(--accent)}
.field.invalid .dobrow select{border-color:var(--danger)}

/* Not asked on the post form. The form keeps its defaults for these (hand-over
   at the gym, a standard time, sold as separate passes, no reason given), and
   the script still toggles the wrappers, so they are hidden here rather than
   removed from the page. */
#wrap-pickup,#wrap-meet,#wrap-split,#wrap-why{display:none!important}

/* ---- forgot password ---- */
#forgot .as-form,#forgot .auth-form{gap:14px}
#forgot .as-field{display:grid;gap:6px}
#forgot .as-lbl{margin:0;color:var(--text);font:500 .875rem/1.2 var(--font)}
#forgot .as-field:has(.invalid) .as-lbl{color:var(--danger)}
#forgot .as-box{gap:10px;padding:0 12px;min-block-size:50px;box-shadow:none}
#forgot .as-box .fico,#forgot .as-box:focus-within .fico{inline-size:20px;block-size:20px;border-radius:0;
  background:none;color:var(--muted)}
#forgot .as-box:focus-within .fico{color:var(--accent)}
#forgot .as-box input{flex:1;min-inline-size:0;border:0;background:none;color:var(--text);padding:0;font:500 1rem/1.2 var(--font)}
#forgot .as-box input:focus{outline:none}
#forgot .as-field .problem{margin:0}
.fp-h{margin:28px 0 8px;font:700 1.375rem/1.2 var(--font);letter-spacing:-.02em}
.fp-sub{margin:0 0 18px;color:var(--muted);font:400 .9375rem/1.5 var(--font)}
.fp-done{display:grid;justify-items:stretch}
.fp-done .btn{margin-top:6px}
.fp-done .as-link{margin:14px auto 0}

.dobcal{display:grid;place-items:center;box-sizing:border-box;inline-size:50px;block-size:50px;padding:0;cursor:pointer;
  border:1.5px solid var(--hair);border-radius:var(--r-m);background:var(--surface);color:var(--accent);
  transition:border-color .15s var(--ease),background .15s var(--ease)}
.dobcal:hover{background:var(--accent-soft)}
.dobcal:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.field.invalid .dobcal{border-color:var(--danger)}

/* Password guidance: four ticks that mirror the strength meter. */
.pwrules{list-style:none;margin:12px 0 0;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:8px 14px}
.pwrules li{display:flex;align-items:center;gap:8px;color:var(--muted);font:400 .8125rem/1.3 var(--font)}
.pwrules li::before{content:"";flex:none;inline-size:16px;block-size:16px;border-radius:50%;
  border:1.5px solid var(--hair);box-sizing:border-box;transition:background .15s var(--ease),border-color .15s var(--ease)}
.pwrules li.ok{color:var(--text)}
.pwrules li.ok::before{border-color:var(--accent);
  background:var(--accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4.2 8.4 2.4 2.4 5-5.2'/%3E%3C/svg%3E") center/100% no-repeat}
@media (max-width:360px){.pwrules{grid-template-columns:1fr}}

/* ---- sign-up complete ---- */
.joined{display:grid;justify-items:start;padding-top:56px!important}
.joined-tick{display:grid;place-items:center;inline-size:64px;block-size:64px;border-radius:50%;
  background:var(--accent);color:var(--on-accent)}
.joined-h{margin:22px 0 6px;font:700 1.75rem/1.15 var(--font);letter-spacing:-.02em}
.joined-s{margin:0;color:var(--muted);font:400 1rem/1.45 var(--font)}
.joined-next{display:grid;gap:4px;margin:26px 0 22px;padding:16px 18px;inline-size:100%;box-sizing:border-box;
  border:1px solid var(--hair);border-radius:var(--r-m);background:var(--surface)}
.joined-next b{font:600 .9375rem/1.3 var(--font)}
.joined-next span{color:var(--muted);font:400 .875rem/1.45 var(--font)}
.joined .btn{inline-size:100%}
.joined .as-link{margin:14px auto 0}
#onboard label.consent[for="ob-agree"]{display:none}

/* ---- first-visit welcome ---- */
#hellosheet .as-head{display:flex;align-items:center;gap:12px}
#hellosheet .as-head .sheet-logo{margin:0;flex:none}
#hellosheet .as-head .sheet-logo .logomark{inline-size:36px;block-size:36px}
#hellosheet .as-head h2{margin:0}
.hello-lede{margin:10px 0 4px!important}
.hello-list{list-style:none;margin:6px 0 18px;padding:0;display:grid;gap:10px}
.hello-list li{padding-inline-start:16px;position:relative;color:var(--muted);font:400 .875rem/1.45 var(--font)}
.hello-list li::before{content:"";position:absolute;inset-inline-start:0;top:.55em;inline-size:6px;block-size:6px;
  border-radius:50%;background:var(--hot)}
.hello-list b{color:var(--text);font-weight:600}
#hellosheet .btn{inline-size:100%}

/* ---- cookie bar ---- */
.cookiebar{position:fixed;z-index:90;inset-inline:12px;bottom:calc(12px + env(safe-area-inset-bottom,0px));
  max-inline-size:560px;margin-inline:auto;display:grid;gap:12px;padding:16px 18px;
  border-radius:var(--r-l);background:var(--surface);color:var(--text);
  box-shadow:0 0 0 1px var(--hair),0 12px 32px rgb(28 15 43 / .16)}
.cookiebar p{margin:0;color:var(--muted);font:400 .8125rem/1.5 var(--font)}
.cookiebar p b{display:block;margin-bottom:4px;color:var(--text);font:600 .9375rem/1.3 var(--font)}
.cb-acts{display:flex;gap:8px;justify-content:flex-end;flex-wrap:wrap}
.cb-acts button{min-block-size:42px;padding:0 18px;border-radius:999px;cursor:pointer;font:600 .875rem/1 var(--font)}
.cb-sec{border:1.5px solid var(--hair);background:var(--surface);color:var(--text)}
.cb-pri{border:0;background:var(--accent);color:var(--on-accent)}
.cb-acts button:focus-visible{outline:2px solid var(--focus);outline-offset:2px}

/* The pass type is plain text; the count of passes left keeps its pill. */
.card2 .tag.kind{padding:0;border-radius:0;background:none;color:var(--text);font:500 .875rem/1.4 var(--font)}
.card2 .c2-tags{align-items:center;gap:6px 12px}

/* ---- illustrations ----
   Drawn in the brand's own shapes: the pass ticket and the two-piece mark, in
   plum, ember and pink. Decorative, so they sit above the words they support. */
.art{display:block;inline-size:100%;max-inline-size:260px;block-size:auto;margin:0 0 18px}
#hellosheet .art{max-inline-size:220px;margin:4px auto 14px}
.joined .art{max-inline-size:220px;margin:0 0 6px}
.ob-step .art{max-inline-size:240px;margin:6px 0 20px}

/* ---- board filter ---- */
.chiprow{display:flex;align-items:center;gap:10px}
.chiprow .filters{flex:1;min-inline-size:0}
.fbtn{flex:none;display:inline-flex;align-items:center;gap:7px;min-block-size:38px;padding:0 14px;cursor:pointer;
  border:1.5px solid var(--hair);border-radius:999px;background:var(--surface);color:var(--text);font:500 .875rem/1 var(--font)}
.fbtn:hover,.fbtn[aria-expanded="true"]{border-color:var(--accent)}
.fbtn.on{border-color:var(--accent)}
.fbtn b{display:grid;place-items:center;min-inline-size:20px;block-size:20px;padding:0 5px;box-sizing:border-box;
  border-radius:999px;background:var(--accent);color:var(--on-accent);font:600 .75rem/1 var(--font)}
.fbtn b[hidden]{display:none}
.fbtn:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.fpanel{display:grid;gap:16px;margin-top:12px;padding:18px;border:1px solid var(--hair);border-radius:var(--r-m);background:var(--surface)}
.fgroup{display:grid;gap:8px}
.flabel{color:var(--text);font:600 .8125rem/1.2 var(--font)}
.fopts{display:flex;flex-wrap:wrap;gap:7px}
.fgroup select{box-sizing:border-box;min-block-size:46px;padding:0 34px 0 14px;border:1.5px solid var(--hair);border-radius:var(--r-m);
  color:var(--text);font:500 .9375rem/1.2 var(--font);-webkit-appearance:none;appearance:none;
  background:var(--surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%235d5068' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 12px center}
.fact{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-top:12px;border-top:1px solid var(--hair)}
.fact .as-link{margin:0}
.fdone{min-block-size:40px;padding:0 18px;border:0;border-radius:999px;cursor:pointer;background:var(--accent);
  color:var(--on-accent);font:600 .875rem/1 var(--font)}

/* "What do you climb?" as picture cards */
#ob-disc{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
#ob-disc .disccard{position:relative;display:grid;justify-items:start;gap:4px;padding:12px;text-align:start;cursor:pointer;
  border:1.5px solid var(--hair);border-radius:var(--r-m);background:var(--surface);color:var(--text)}
#ob-disc .disccard svg{inline-size:100%;block-size:auto;margin-bottom:6px;border-radius:10px;background:var(--accent-soft)}
#ob-disc .disccard b{font:600 .9375rem/1.2 var(--font)}
#ob-disc .disccard span{color:var(--muted);font:400 .75rem/1.35 var(--font)}
#ob-disc .disccard[aria-pressed="true"]{border:2px solid var(--accent);padding:11.5px;background:var(--surface);color:var(--text)}
#ob-disc .disccard[aria-pressed="true"]::after{content:"";position:absolute;top:8px;inset-inline-end:8px;inline-size:22px;block-size:22px;
  border-radius:50%;background:var(--accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4.2 8.4 2.4 2.4 5-5.2'/%3E%3C/svg%3E") center/70% no-repeat}
#ob-disc .disccard:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
@media (max-width:420px){#ob-disc{grid-template-columns:1fr}
  #ob-disc .disccard{grid-template-columns:96px 1fr;column-gap:14px;align-items:center}
  #ob-disc .disccard svg{margin:0}}
/* Illustrations sit centred above the words. */
.ob-step .art{margin-inline:auto}
.joined .art{justify-self:center;margin-inline:auto}

/* First-visit welcome: each point is a row with its own drawing. */
#hellosheet .hello-list{gap:8px}
#hellosheet .hello-list li{display:flex;align-items:center;gap:12px;padding:8px;padding-inline-start:8px;
  border:1px solid var(--hair);border-radius:var(--r-m);background:var(--surface)}
#hellosheet .hello-list li::before{content:none}
#hellosheet .hello-list li svg{flex:none;inline-size:52px;block-size:52px;border-radius:10px;background:var(--accent-soft)}
#hellosheet .hello-list li span{color:var(--muted);font:400 .8125rem/1.45 var(--font)}
#hellosheet .hello-list li b{display:block;color:var(--text);font:600 .875rem/1.3 var(--font)}

/* ---- done dialog ---- */
.donebox{text-align:center}
.donebox .done-art{max-inline-size:180px;margin:0 auto 6px}
.donebox h2{margin:0 0 6px;font-size:1.375rem!important;letter-spacing:-.02em}
.donebox p{margin:0 0 18px!important;font-size:.875rem!important;line-height:1.5!important}
.donebox .btn{inline-size:100%}
.donebox .as-link{margin:12px auto 0}

/* Review mocks (/mocks): a dialog on its own, nothing behind it. */
.mock-solo body{background:var(--bg,#faf6f3)}
.mock-solo body>*{visibility:hidden}
.mock-solo .sheet.on,.mock-solo .sheet.on *,.mock-solo #toast,.mock-solo #toast *,
.mock-solo .cookiebar,.mock-solo .cookiebar *{visibility:visible}
.mock-solo .sheet{background:transparent;backdrop-filter:none}

/* ---- the site footer on phones too ----
   Every page ends the same way: who Spare is, the rules, and how to reach us.
   Stacked for a phone, with room underneath for the tab bar. The little
   per-screen footers step aside except on sign-in screens, where they carry
   the terms line. */
@media (max-width:759px){
  .sitefoot{display:block;background:var(--surface);border-top:1px solid var(--hair);
    padding-bottom:calc(76px + env(safe-area-inset-bottom,0px))}
  body.auth .sitefoot{display:none}
  body:not(.auth) .appfoot{display:none}
  .sf-in{padding:28px 20px 18px;display:grid;grid-template-columns:1fr 1fr;gap:22px 16px}
  .sf-brand{grid-column:1/-1}
  .sf-logo{display:flex;align-items:center;gap:8px;color:var(--text);font:600 1.125rem/1 var(--font);letter-spacing:-.03em}
  .sf-logo .logomark{font-size:1.5rem}
  .sf-tag{margin:12px 0 0;font:500 .875rem/1.5 var(--font);color:var(--text)}
  .sf-say{margin:6px 0 0;font:400 .8125rem/1.55 var(--font);color:var(--muted)}
  .sf-col{display:flex;flex-direction:column;align-items:flex-start;gap:11px}
  .sf-col h4{margin:0 0 2px;font:600 .6875rem/1 var(--font);letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
  .sf-col button,.sf-col a{border:0;background:none;padding:0;cursor:pointer;text-align:left;
    color:var(--text);text-decoration:none;font:400 .875rem/1.3 var(--font)}
  .sf-bottom{padding:14px 20px 4px;border-top:1px solid var(--hair);display:flex;flex-wrap:wrap;
    justify-content:space-between;gap:6px 14px;color:var(--muted);font:400 .75rem/1.4 var(--font)}
}
/* The chip row normally bleeds to the screen edges to scroll; beside the
   Filter button it has to stop short of it instead of sliding underneath. */
.chiprow>.filters{margin-inline:0!important;padding-inline:0!important}
/* Two-option switches in Settings sit at the right of their row, as wide as
   their words, instead of dropping to a full-width line of their own. */
.item:has(.langswitch){flex-wrap:nowrap;align-items:center}
.item .langswitch{display:inline-flex;flex:0 0 auto;inline-size:max-content;margin:0 0 0 auto;padding:3px}
.item .langswitch button{flex:0 0 auto;padding:7px 14px}

#ig-row{text-decoration:none;color:inherit}
#ig-row .ig-at{color:var(--muted);margin-inline-start:6px}

/* Notifications, when there are none */
.alerts.is-empty{background:var(--surface)}
.alerts-empty{display:grid;justify-items:center;gap:6px;padding:28px 18px;text-align:center}
.alerts-empty svg{inline-size:120px;block-size:auto}
.alerts-empty b{font:600 1rem/1.3 var(--font)}
.alerts-empty span{max-inline-size:28ch;color:var(--muted);font:400 .875rem/1.45 var(--font)}

.c2-top .c2-mine{flex:none;align-self:flex-start}

/* ---- phones: a top bar on the main screens ---- */
.mtop{display:none}
@media (max-width:759px){
  body:not(.auth)[data-screen="detail"] .mtop,body:not(.auth)[data-screen="profile"] .mtop,
  body:not(.auth)[data-screen="alerts"] .mtop,body:not(.auth)[data-screen="settings"] .mtop,
  body:not(.auth)[data-screen="post"] .mtop,body:not(.auth)[data-screen="user"] .mtop,
  body:not(.auth)[data-screen="rules"] .mtop,body:not(.auth)[data-screen="terms"] .mtop,
  body:not(.auth)[data-screen="privacy"] .mtop{
    display:flex;align-items:center;justify-content:space-between;gap:12px;position:sticky;
    top:0;z-index:40;margin:0 calc(-1*var(--gutter,16px)) 10px;
    padding:calc(10px + env(safe-area-inset-top,0px)) var(--gutter,16px) 10px;background:var(--accent);color:#fff}
  .mt-brand{display:flex;align-items:center;gap:8px;border:0;background:none;padding:0;cursor:pointer;color:#fff;
    font:700 1.0625rem/1 'Space Grotesk',var(--font);letter-spacing:-.03em}
  .mt-brand .logomark{inline-size:24px;block-size:24px}
  .mt-end{display:flex;align-items:center;gap:10px}
  .mt-bell{position:relative;display:grid;place-items:center;inline-size:38px;block-size:38px;border:0;border-radius:50%;
    background:var(--plum-raised,#3d2456);color:#fff;cursor:pointer}
  .mt-dot{position:absolute;top:2px;right:2px;min-inline-size:16px;block-size:16px;padding:0 4px;box-sizing:border-box;
    border-radius:999px;background:var(--hot);color:var(--on-hot);font:700 .625rem/16px var(--font);text-align:center}
  .mt-me{border:0;background:none;padding:0;cursor:pointer}
  .mt-me .face{display:grid;place-items:center;inline-size:34px;block-size:34px;border-radius:50%;overflow:hidden;
    background:var(--hot);color:var(--on-hot);font:600 .75rem/1 var(--font)}
  .mt-me .face img{inline-size:100%;block-size:100%;object-fit:cover}
  .mt-signin{border:0;border-radius:999px;padding:9px 14px;background:var(--hot);color:var(--on-hot);cursor:pointer;font:600 .8125rem/1 var(--font)}
}
/* The Me tab shows your face once you are signed in. */
.tab .tabface{display:grid;place-items:center;inline-size:24px;block-size:24px;border-radius:50%;overflow:hidden;
  background:var(--accent);color:var(--on-accent);font:600 .5625rem/1 var(--font)}
.tab .tabface img{inline-size:100%;block-size:100%;object-fit:cover}
.tab[aria-current="page"] .tabface{box-shadow:0 0 0 2px var(--surface),0 0 0 3.5px var(--accent)}

/* ---- the narrowest phones (the original Galaxy Fold, folded: 280px) ---- */
#signin .auth-form,#authsheet .as-form,#forgot .auth-form{grid-template-columns:minmax(0,1fr)}
.as-field,.as-box{min-inline-size:0}
.as-box input{inline-size:100%;min-inline-size:0}
@media (max-width:359px){
  .item:has(.langswitch){flex-wrap:wrap}
  .item .langswitch{margin:8px 0 0 auto}
}
/* Tap targets and the smallest text */
.skip{padding:12px 6px;margin:-12px -6px;min-block-size:40px}
.seller-badge{font-size:.75rem}

/* ---- desktop top bar in plum, like the phones' ---- */
@media (min-width:760px){
  .topbar{background:var(--accent);border-bottom:0;box-shadow:none;color:#fff}
  .tb-brand,.tb-brand b{color:#fff}
  .tb-seg{background:var(--plum-raised,#3d2456)}
  .tb-seg button{color:#d9c6e6}
  .tb-seg button[aria-pressed="true"]{background:#fff;color:var(--accent)}
  .tb-search{background:#fff;border:0}
  .tb-icon{color:#fff;background:var(--plum-raised,#3d2456)}
  .tb-icon:hover{background:#4c2f6a}
  .tb-icon .dot{background:var(--hot);color:var(--on-hot)}
  .tb-signin{border:0;background:var(--plum-raised,#3d2456);color:#fff}
  .tb-me{color:#fff}
  .tb-me:hover,.tb-me[aria-current="true"]{background:var(--plum-raised,#3d2456)}
  .tb-me .face{background:var(--hot);color:var(--on-hot)}
  .tb-post{background:var(--hot);color:var(--on-hot)}
}

/* Desktop: Give / Take sits first in the chip row, before All, instead of in
   the top bar. The script moves the switch there on wide screens and back to
   its own row on phones. */
@media (min-width:760px){
  .tb-seg{display:none}
  .chiprow>#seg{display:flex;flex:none;margin:0}
}

/* Desktop profile: two columns under the header and the numbers. */
@media (min-width:960px){
  #profile .pro-cols{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:8px 36px;align-items:start}
  #profile .pro-side>.sechead:first-child{margin-top:4px}
  #profile .pro-side>.sechead:first-child .seclabel{margin-top:0}
  /* Two columns need the room the single column did not. */
  .shell > #profile.screen{max-inline-size:min(68rem,100%)}
}

/* The Post banner: a little room under the top bar, and a drawing in the space
   on its right (two passes and a plus), sized down on phones. */
.promo{position:relative}
.promo .promo-art{flex:none;margin-inline-start:auto;inline-size:118px;block-size:auto}
@media (max-width:419px){.promo .promo-art{display:none}}
@media (min-width:760px){
  .promo{margin-top:22px;padding:20px 26px}
  .promo .promo-art{inline-size:170px;margin-block:-6px}
}

/* One height for everything on the chip row: the switch, the chips, Filter. */
.chiprow{align-items:center}
.chiprow>.filters{padding-block:0!important;align-items:center}
.chiprow .chip,.chiprow .fbtn{box-sizing:border-box;block-size:40px;min-block-size:40px;display:inline-flex;align-items:center}
.chiprow>#seg{box-sizing:border-box;block-size:40px;padding:3px;align-items:stretch}
.chiprow>#seg button{block-size:auto;min-block-size:0;padding-block:0;display:inline-flex;align-items:center}
.chiprow{margin-top:12px}
.countrow>#seg{box-sizing:border-box;block-size:40px;padding:3px;align-items:stretch}
.countrow>#seg button{block-size:auto;min-block-size:0;padding-block:0;display:inline-flex;align-items:center}

/* Messages: the title and icon sit inside the white box. */
.msgarea .msghead{display:flex;align-items:center;gap:8px;margin:0 0 14px;padding-bottom:12px;border-bottom:1px solid var(--hair);font-size:1rem;font-weight:600;line-height:1.2}
.msgarea .msghead svg{color:var(--accent);flex:none}
.notice .notice-body{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px}

/* Safety line sits on the right of the Messages title. */
.msgarea .msgtop{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:6px 12px;margin:0 0 14px;padding-bottom:12px;border-bottom:1px solid var(--hair)}
.msgarea .msgtop .msghead{margin:0;padding:0;border:0}
.msgarea .msgtop .notice{margin:0;padding:0;background:none;border:0;font-size:.8125rem;gap:6px;align-items:center}
.msgarea .msgtop .notice-stub svg{inline-size:18px;block-size:18px}
.msgarea .msgtop{flex-wrap:nowrap}
.msgarea .msgtop .notice{margin-left:auto;text-align:end;font-size:.75rem;line-height:1.3}
.msgarea .msgtop .notice-body{display:grid;justify-items:end;gap:2px}
.msgarea .msgtop .notice-body b{font-weight:400}
.msgarea .msgtop .notice-body b,.msgarea .msgtop .notice-body button{font-size:.6875rem}.msgarea .msgtop .notice-stub svg{inline-size:15px;block-size:15px}
/* Messages header: room above the box, one tidy row, icon on the text line. */
#detail .msgarea{margin-top:20px}
.msgarea .msgtop{align-items:center;margin:0 0 16px;padding-bottom:14px}
.msgarea .msgtop .notice{display:flex;align-items:center;gap:6px;line-height:1.25}
.msgarea .msgtop .notice-stub{display:flex}
.msgarea .msgtop .notice-body{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:baseline;gap:0 8px}

.thread .msgwho{font-size:.75rem;font-weight:600;color:var(--muted);margin:10px 4px 4px}
.thread .msgwho.me{text-align:end}
.thread .msg{inline-size:fit-content}
/* Title and safety line share one 24px line, so their text lines up. */
.msgarea .msgtop{align-items:center}
.msgarea .msgtop .msghead,.msgarea .msgtop .notice,.msgarea .msgtop .notice-body{min-block-size:24px;align-items:center;line-height:24px}
.msgarea .msgtop .notice-body b,.msgarea .msgtop .notice-body button{line-height:24px}

.thread .msgtime{font-size:.6875rem;color:var(--muted);margin:3px 6px 8px}
.thread .msgtime.me{text-align:end}
.thread .msg + .msgtime{margin-top:3px}

.msgarea .msghead .mh-t{display:grid;line-height:1.2}
.msgarea .msghead small{font-size:.75rem;font-weight:400;color:var(--muted);line-height:1.3}
.msgarea .msgtop .msghead{line-height:1.2}

/* ---- edit profile ---- */
.pro .pro-id{flex:1;min-inline-size:0}
.pro .ed-open{flex:none;min-block-size:38px;padding:0 14px;font-size:.8125rem;inline-size:auto}
.pro-bio{margin:10px 0 0;color:var(--ink,inherit);font-size:.9375rem;line-height:1.45;white-space:pre-line;overflow-wrap:anywhere}
.pro-ig{display:inline-block;margin-top:6px;color:var(--hot);font-size:.875rem;font-weight:600}
.face img{inline-size:100%;block-size:100%;object-fit:cover;border-radius:50%}
.edform{display:grid;gap:14px}
.edform .as-head{display:flex;align-items:center;justify-content:space-between}
.edform .ed-x{border:0;background:none;color:var(--muted);font:inherit;font-weight:500;cursor:pointer;min-block-size:44px}
.edform textarea{inline-size:100%;border:0;background:none;font:inherit;resize:vertical;padding:10px 0;color:inherit}
.edform textarea:focus{outline:none}
.edform select{inline-size:100%;border:0;background:none;font:inherit;color:inherit;min-block-size:44px}
.edform .ed-count{float:right;font-weight:400;color:var(--muted);font-size:.75rem}
.edform .ed-two{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px}
@media (max-width:359px){.edform .ed-two{grid-template-columns:minmax(0,1fr)}}
.edform .ig-pre{font-weight:600;color:var(--muted)}
button.item.asrow{inline-size:100%;text-align:start;font:inherit;color:inherit;background:none;border-inline:0;border-block-start:0;cursor:pointer}
.edform input{inline-size:100%;min-inline-size:0;border:0;background:none;font:inherit;color:inherit;min-block-size:44px;padding:0;outline:none;box-shadow:none}
.edform .ifield.as-box:focus-within{border-color:var(--accent)}
.edform .ig-pre{background:none!important;inline-size:auto;padding-inline-end:2px}
.edform .as-box{padding-inline:14px}

.empty .ask-cta{display:flex;margin:12px auto 0;inline-size:auto;min-block-size:44px;padding:0 18px}

#detail #offersug button[data-offer].on{background:#2b1640!important;color:#fff!important;border-color:transparent!important}

/* Phones: the safety line goes under the title, on one line, icon beside it. */
@media (max-width:480px){
  .msgarea .msgtop{flex-wrap:wrap}
  .msgarea .msgtop .notice{margin-left:0;inline-size:100%;justify-content:flex-start;text-align:start}
  .msgarea .msgtop .notice-body{justify-content:flex-start;flex-wrap:nowrap;white-space:nowrap}
}
/* One clear button on search: ours, not the browser's as well. */
#q::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none;display:none}

/* Your own pass: no offer to yourself, no card introducing you to yourself. */
#detail.is-mine .offerbox > :not(.offerhead),#detail.is-mine #claim,#detail.is-mine #seller{display:none}
#detail.is-mine .offerbox{padding-block-end:4px}
.empty .ask-cta{border:1.5px solid #2b1640!important;background:#fff!important;color:#2b1640!important;border-radius:999px;font-weight:600;align-items:center;justify-content:center}
/* Your own pass: the summary box breathes, and has no divider with nothing under it. */
#detail.is-mine .offerbox{padding:20px 22px!important}
#detail.is-mine .offerhead{border-bottom:0!important;padding-bottom:0!important;margin-bottom:0!important;row-gap:10px;column-gap:14px;flex-wrap:wrap}
#detail.is-mine .offerhead .gone{margin-left:auto}
#detail.is-mine .offerhead .listed{flex-basis:100%;margin:0!important;justify-content:flex-start;text-align:start}

#detail.is-mine #d-mybid{border-top:0!important;margin-top:8px}
#detail.is-mine #d-mybid .bids{border-top:0!important;padding-top:0}

#wrap-price #hint-price{display:block;margin:2px 0 4px;font-weight:400}
#wrap-price #hint-price[hidden]{display:none}
/* The phone top bar runs edge to edge like the bottom bar, at any width up to
   the desktop switch, with its contents lined up with the column. */
@media (max-width:759px){
  body:not(.auth) .mtop{margin-inline:calc(50% - 50vw)!important;
    padding-inline:calc(50vw - 50% + var(--gutter,16px))!important}
}
/* The price hint makes its column taller than Passes; stacked, nothing misaligns. */
#post #wrap-row{grid-template-columns:minmax(0,1fr)!important;row-gap:14px}
/* Phones: one calm header. Title and start time, then a single quiet line of
   safety underneath, instead of two columns fighting for 300px. */
@media (max-width:520px){
  #detail .msgarea .msgtop{display:grid!important;grid-template-columns:minmax(0,1fr);row-gap:8px;align-items:start}
  #detail .msgarea .msgtop .msghead{align-items:flex-start}
  #detail .msgarea .msghead .mh-t small{white-space:nowrap}
  #detail .msgarea .msgtop .notice{margin:0!important;inline-size:auto;justify-content:flex-start!important;
    text-align:start!important;min-block-size:0;line-height:1.3}
  #detail .msgarea .msgtop .notice-body{display:flex!important;flex-wrap:wrap;justify-content:flex-start!important;
    gap:0 8px;min-block-size:0;line-height:1.3}
  #detail .msgarea .msgtop .notice-body b,#detail .msgarea .msgtop .notice-body button{line-height:1.3;font-size:.75rem}
  #detail .msgarea .msgtop .notice-stub svg{inline-size:14px;block-size:14px}
}

@media (max-width:759px){
  #feed .countrow{display:flex;align-items:center;gap:10px}
  #feed .countrow #fbtn{margin-left:auto;flex:none}
  #feed .chiprow > .filters{margin-inline-end:calc(-1*var(--gutter,16px))!important}
}
/* Connection notices drop down from the top bar instead of hiding behind the
   bottom tabs. */
.backendbar{top:0;bottom:auto!important;z-index:120;
  padding:calc(10px + env(safe-area-inset-top,0px)) 16px 10px!important;
  background:var(--hot,#ff6b3d);color:var(--on-hot,#1c0f2b);font-weight:600;font-size:.8125rem;
  box-shadow:0 6px 18px rgb(28 15 43 / .18);animation:bbdrop .28s ease-out}
.backendbar[data-tone="info"]{background:#3d2456;color:#fff}
@keyframes bbdrop{from{transform:translateY(-100%)}to{transform:none}}
@media (prefers-reduced-motion:reduce){.backendbar{animation:none}}
body .backendbar[data-tone]{background:#ff6b3d;color:#1c0f2b}
body .backendbar[data-tone="info"]{background:#3d2456;color:#fff}
body .backendbar.under-bar{padding-top:10px!important;border-radius:0 0 14px 14px;inset-inline:max(0px,calc(50% - 20rem))}
/* Connection banner: flat deep red, white text, a no-signal icon. */
body .backendbar[data-tone]{background:#b3261e!important;color:#fff!important;border:0!important;border-radius:0!important;box-shadow:none!important;
  display:flex;align-items:center;justify-content:center;gap:8px}
body .backendbar[data-tone="info"]{background:#3d2456!important}
body .backendbar[hidden]{display:none!important}
body .backendbar[data-tone]::before{content:"";flex:none;inline-size:16px;block-size:16px;background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 8.8a15 15 0 0 1 4.2-2.6M9.5 5.3A15 15 0 0 1 22 8.8M5 12.5a10 10 0 0 1 3.2-2M15.5 10.6A10 10 0 0 1 19 12.5M8.5 16a5 5 0 0 1 7 0M12 19.5h.01M3 3l18 18'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 8.8a15 15 0 0 1 4.2-2.6M9.5 5.3A15 15 0 0 1 22 8.8M5 12.5a10 10 0 0 1 3.2-2M15.5 10.6A10 10 0 0 1 19 12.5M8.5 16a5 5 0 0 1 7 0M12 19.5h.01M3 3l18 18'/%3E%3C/svg%3E") center/contain no-repeat}
body .backendbar.under-bar{inset-inline:0!important}

/* Offline: a red no-signal sign beside the logo in every top bar. */
.mt-brand,.tb-brand,.brandrow{position:relative}
body.is-offline .mt-brand::after,body.is-offline .tb-brand::after,body.is-offline #feed .brandrow::after{
  content:"";display:inline-block;margin-inline-start:8px;inline-size:20px;block-size:20px;border-radius:50%;flex:none;
  background:#b3261e url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5a10 10 0 0 1 3.2-2M15.5 10.6A10 10 0 0 1 19 12.5M8.5 16a5 5 0 0 1 7 0M12 19.5h.01M4 4l16 16'/%3E%3C/svg%3E") center/13px no-repeat;
  vertical-align:middle;box-shadow:0 0 0 2px rgb(255 255 255 / .9)}

#d-follow[aria-pressed="true"] svg{fill:#ff6b3d;stroke:#ff6b3d}
#d-follow[aria-pressed="true"]{color:var(--ink,#1c0f2b);font-weight:600}

/* ---- profile, as in the approved proposal ---- */
#my-sub .pro-line{display:block;font-size:.8125rem;color:var(--muted);line-height:1.45}
#my-sub .pro-line b{font-weight:600;color:var(--ink,inherit);margin-inline-end:4px}
.pro-gyms{display:flex;flex-wrap:wrap;gap:8px;margin:12px 0 4px}
.pro-gyms .gchip{display:inline-flex;align-items:center;gap:6px;min-block-size:34px;padding:4px 12px 4px 6px;border-radius:999px;
  background:#fff;border:1px solid var(--hair);font-size:.8125rem;font-weight:500}
.pro-gyms .gchip .mark,.pro-gyms .gchip img,.pro-gyms .gchip svg{inline-size:22px;block-size:22px}
.pro-gyms .gchip.add{padding-inline:12px;border-style:dashed;background:none;cursor:pointer;color:var(--muted);font:inherit;font-size:.8125rem}
.ptabs{display:none}
@media (max-width:959px){
  .ptabs{display:flex;gap:4px;padding:4px;border-radius:999px;background:var(--tint,#f5edf3);margin:18px 0 6px}
  .ptabs button{flex:1;min-block-size:40px;border:0;border-radius:999px;background:none;font:inherit;font-size:.875rem;font-weight:500;color:var(--muted);cursor:pointer}
  .ptabs button[aria-selected="true"]{background:#fff;color:var(--ink,#1c0f2b);font-weight:600;box-shadow:0 1px 3px rgb(28 15 43 / .1)}
  #profile .pgroup.ptab-off{display:none}
  #profile .pgroup[data-pg="where"]{display:none}
  #profile .pgroup > .seclabel:first-child,#profile .pgroup > .sechead:first-child .seclabel{display:none}
}
/* The bottom bar marks where you are: the current tab is red, and Post is red
   only while you are posting. */
.tab#fab{color:var(--muted)}
.tab[aria-current="page"],body[data-screen="post"] .tab#fab{color:var(--hot-text,#d9481c)}
body[data-screen="post"] .tab[aria-current="page"]:not(#fab){color:var(--muted)}
body[data-screen="post"] .tab#fab .lbl{font-weight:600}

.histrow .tag2.sold{background:#f3e6e6;color:#8a2a22}
.histrow .reopen{border:1px solid var(--hair);background:#fff;border-radius:999px;padding:6px 12px;font:inherit;font-size:.75rem;font-weight:600;cursor:pointer;min-block-size:32px}
/* Search: tapping it keeps it a clean white field, no ring or border. */
#q:focus,#q:focus-visible,#tq:focus,#tq:focus-visible{outline:none!important;box-shadow:none!important;border:0!important;background:transparent!important}
#search:focus-within,.search:focus-within,.tb-search:focus-within{outline:none!important;box-shadow:none!important;border-color:transparent!important;background:#fff!important}
/* Pull to refresh */
.ptr{position:fixed;top:calc(env(safe-area-inset-top,0px) + 8px);left:50%;z-index:130;inline-size:38px;block-size:38px;border-radius:50%;
  display:grid;place-items:center;background:#fff;color:#2b1640;box-shadow:0 4px 14px rgb(28 15 43 / .18);opacity:0;
  transform:translate(-50%,-40px);transition:opacity .15s;pointer-events:none}
.ptr.ready{color:#ff6b3d}
.ptr.spin svg{animation:ptrspin .7s linear infinite}
@keyframes ptrspin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.ptr.spin svg{animation:none}}

#feed .chiprow{justify-content:flex-start;gap:10px}
@media (min-width:760px){#feed .chiprow #fbtn{margin-left:auto}}

/* ---- floating Post button (phones) ---- */
#bar{grid-template-columns:repeat(3,1fr)!important}
.fab{position:fixed;z-index:55;inset-inline-end:max(18px,calc(50% - 17rem + 18px));
  bottom:calc(58px + 18px + env(safe-area-inset-bottom,0px));
  inline-size:58px;block-size:58px;border-radius:50%;border:0;display:grid;place-items:center;cursor:pointer;
  background:#ff6b3d;color:#1c0f2b;box-shadow:0 8px 22px rgb(255 107 61 / .38),0 2px 6px rgb(28 15 43 / .18);
  transition:transform .15s ease}
.fab:active{transform:scale(.94)}
.fab:focus-visible{outline:3px solid #2b1640;outline-offset:3px}
/* Only where there is something to post from: not on forms, a pass page, or sign-in. */
body.auth .fab,
body:not([data-screen="feed"]):not([data-screen="alerts"]):not([data-screen="profile"]):not([data-screen="user"]) .fab{display:none}
@media (min-width:960px){.fab{display:none!important}}
/* Room under the last card so the floating button never sits on top of it. */
@media (max-width:959px){#feed,#alerts,#profile,#user{padding-bottom:84px}}

/* Notifications live behind the bell in the top bar, so the bar is two tabs. */
#bar{grid-template-columns:repeat(2,1fr)!important}

.ptabs .ptab-n{display:inline-grid;place-items:center;min-inline-size:20px;block-size:20px;padding:0 6px;margin-inline-start:4px;border-radius:999px;background:#f5edf3;font-size:.75rem;font-weight:600}
.ptabs [aria-selected="true"] .ptab-n{background:#2b1640;color:#fff}
.blocklist .empty-post{margin-top:12px;inline-size:auto;min-block-size:42px;padding:0 16px}
.ptabs button{white-space:nowrap;font-size:.8125rem!important;padding-inline:6px}
.ptabs .ptab-n{min-inline-size:18px;block-size:18px;font-size:.6875rem;padding:0 5px;vertical-align:1px}
/* Desktop has "Post a pass" in its top bar: no floating button from the width
   the top bar takes over. */
@media (min-width:760px){.fab{display:none!important}}
@media (min-width:760px){#feed,#alerts,#profile,#user{padding-bottom:0}}
/* Floating Post: a plain button, no orange glow. */
.fab{box-shadow:0 2px 6px rgb(28 15 43 / .18)!important}

/* Board cards lead with the poster, not the gym logo. */
.card2 .c2-face{flex:none;inline-size:44px;block-size:44px;border-radius:50%;display:grid;place-items:center;overflow:hidden;
  background:#2b1640;color:#fff;font:600 .875rem/1 var(--font)}
.card2 .c2-face img{inline-size:100%;block-size:100%;object-fit:cover}

/* The poster's face wherever a pass or request is listed, sized like the mark it replaces. */
.c2-face,.ohead .c2-face,.histrow .c2-face,.card-h .c2-face,#d-mark .c2-face{flex:none;inline-size:44px;block-size:44px;border-radius:50%;display:grid;place-items:center;overflow:hidden;
  background:#2b1640;color:#fff;font:600 .875rem/1 var(--font)}
.c2-face img{inline-size:100%;block-size:100%;object-fit:cover}
.histrow .c2-face,.ohead .c2-face{inline-size:38px;block-size:38px;font-size:.75rem}
#d-mark .c2-face{inline-size:48px;block-size:48px;font-size:1rem}

/* Price on the pass page, visible to everyone (the offer controls are only for signed-in people). */
.offerhead .d-price{margin-inline-start:auto;font-size:.875rem;color:var(--muted,#5d5068)}
.offerhead .d-price b{font-size:1.25rem;color:var(--ink,#1c0f2b);margin-inline-end:4px}
.offerhead .d-price b.free{color:#2f7d4f}
/* Signed out, the feed's "Got a pass you won't use?" banner is the one Post
   button; the floating + appears once someone can actually post. */
body.guest .fab{display:none}
/* Report shares the action row: pushed to the end, and just the flag on phones
   so Save, Follow gym, Share and Report fit on one line. */
#detail .d-actions{flex-wrap:nowrap;gap:16px}
#detail .d-report{margin-inline-start:auto}
@media (max-width:480px){#detail #d-report-label{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}}

/* Post is the middle tab: Browse · Post · Me. An orange disc, so the one thing
   we want people to do is the easiest thing to reach with a thumb. */
#bar{grid-template-columns:repeat(3,1fr)!important}
.tab-post .post-dot{display:grid;place-items:center;inline-size:30px;block-size:30px;margin-block:-4px;
  border-radius:50%;background:#ff6b3d;color:#1c0f2b}
.tab-post .post-dot svg{inline-size:18px;block-size:18px}
.tab-post:active .post-dot{transform:scale(.94)}
.tab-post:focus-visible{outline:none}
.tab-post:focus-visible .post-dot{outline:3px solid #2b1640;outline-offset:3px}
/* iPhone Safari zooms into any field whose text is under 16px and stays zoomed,
   which reads as the whole app overflowing to the right. 16px on phones stops
   it; `clip` (unlike `hidden`) keeps sticky headers working while making sure
   nothing can pan the page sideways. */
@media (max-width:760px){
  input:not([type=checkbox]):not([type=radio]):not([type=file]),textarea,select{font-size:16px!important}
}
html,body{overflow-x:clip}
/* No pinch or double-tap zoom: the app is laid out for the phone already. */
html{touch-action:pan-x pan-y}
/* While a remembered session is being restored, no Sign in flash. */
html.auth-pending #tsignin,html.auth-pending #mtsignin{visibility:hidden}
/* Your own face is plum everywhere (Me tab, profile, top bar). On the plum
   top bar a white ring keeps it visible. Orange is kept for actions. */
.mt-me .face{background:#2b1640!important;color:#fff!important;box-shadow:0 0 0 2px #fff}
/* Give / Take is the board's main switch: the chosen side is a solid orange pill. */
.seg button[aria-pressed="true"],[data-tb-side][aria-pressed="true"]{background:#ff6b3d!important;color:#1c0f2b!important;box-shadow:none!important}
.seg button[aria-pressed="true"],[data-tb-side][aria-pressed="true"]{color:#fff!important;font-weight:600}
/* Phones: one top bar on every screen, the board included (its own logo row
   goes; its search box stays under the bar). Post sits where Sign in was, so
   the bottom bar is back to Browse and Me. */
.mt-post{display:inline-flex;align-items:center;gap:6px}
#bar .tab-post{display:none!important}
#bar{grid-template-columns:repeat(2,1fr)!important}
@media (max-width:759px){
  body:not(.auth)[data-screen="feed"] .mtop{display:flex;align-items:center;justify-content:space-between;gap:12px;position:sticky;
    top:0;z-index:40;margin:0 calc(-1*var(--gutter,16px)) 0;
    padding:calc(10px + env(safe-area-inset-top,0px)) var(--gutter,16px) 10px;background:var(--accent);color:#fff}
  #feed .feedhead header.top{display:none!important}
}
@media (max-width:759px){body:not(.auth)[data-screen="feed"] #feed{margin-top:-14px}}
/* One look for every switch in the app: the chosen option is an orange pill
   with white text (Give/Take, profile tabs, history filter, Selling/Giving away). */
.seg button[aria-pressed="true"],[data-tb-side][aria-pressed="true"],
.ptabs button[aria-selected="true"],
.histfilter button[aria-pressed="true"],
.segrow .segbtn.on{background:#ff6b3d!important;border-color:#ff6b3d!important;color:#fff!important;font-weight:600;box-shadow:none!important}
/* Chosen chips follow the same rule as switches: orange, white text. */
.picksug button[aria-pressed="true"]{background:#ff6b3d!important;border-color:#ff6b3d!important;color:#fff!important;font-weight:600}
/* One stepper look: plum circles with a white sign, same size for passes and price. */
.stepper button,.stepfield button{inline-size:36px!important;block-size:36px!important;margin-block:0!important;
  border:0!important;border-radius:50%!important;background:#2b1640!important;color:#fff!important;
  display:grid;place-items:center;font:600 1.125rem/1 var(--font)}
.stepper button:disabled,.stepfield button:disabled{opacity:.35}
/* Secondary buttons are white outlined pills (as Edit profile); filled colour is for the main action. */
.seller-go{background:#fff!important;color:#1c0f2b!important;border:1px solid var(--hair,#ece3ea)!important}
#detail #offersug button[data-offer].on{background:#ff6b3d!important;color:#fff!important;border-color:#ff6b3d!important;font-weight:600}
/* Every chosen option, everywhere (filters, form chips, date and gym pickers),
   uses the same orange as the switches. Progress dots and step bars stay plum:
   they show where you are, not what you picked. */
.chip[aria-pressed="true"],.pickchips button[aria-pressed="true"],.pk-day[aria-pressed="true"],
.pk-years button[aria-pressed="true"],.pk-grid button[aria-pressed="true"],.segbtn.on{
  background:#ff6b3d!important;border-color:#ff6b3d!important;color:#fff!important;font-weight:600}
/* Anything scrolled into view stops below the sticky top bar, not under it. */
@media (max-width:759px){#supply-h,#cards,.seclabel,h2{scroll-margin-top:calc(72px + env(safe-area-inset-top,0px))}}
/* Date of birth on small phones: tighter so Day / Month / Year read in full. */
@media (max-width:400px){
  .dobrow{grid-template-columns:1.05fr 1.3fr 1.1fr auto;gap:6px}
  .dobrow select{padding:0 22px 0 10px;background-position:right 7px center}
}
/* Signed in, Post lives in the top bar; the feed banner would be a second one. */
body:not(.guest) .promo{display:none}
/* Already on the post form: no Post button pointing at itself. */
body[data-screen="post"] #mtpost{visibility:hidden}
/* Edit profile on phones: gym names are long, so gym and town get a row each. */
@media (max-width:480px){.ed-two{grid-template-columns:1fr!important}}
/* Both steppers sit on the card itself, with no grey pill around one of them. */
.stepper{background:none!important;box-shadow:none!important;border:0!important;padding:0!important;gap:12px}
/* A pass with nothing left: the offer controls go, the card loses its error state. */
#detail.is-gone .offerrow,#detail.is-gone #offersug,#detail.is-gone .askrow,#detail.is-gone #err-offer{display:none!important}
#detail.is-gone .offerbox{border-color:var(--hair,#ece3ea)!important}
#detail.is-gone .offerhead{border-bottom:0!important;padding-bottom:0!important;margin-bottom:0!important}
/* With your own accepted request showing below, a disabled "Accepted" button says it twice. */
#detail.is-gone:has(#d-mybid:not([hidden])) #claim{display:none}
/* The main action in a row is orange: Accept, Confirm handover, Send. */
.acc,#send,#u-send{background:#ff6b3d!important;color:#fff!important;border-color:#ff6b3d!important}
/* Your own listing: nothing to save or report. */
#detail.is-mine .d-save,#detail.is-mine .d-report{display:none!important}
/* Phones: the STAGING ribbon sat on the logo; bottom-left above the tab bar covers nothing. */
@media (max-width:759px){.envmark{inset-block-start:auto!important;inset-block-end:calc(66px + env(safe-area-inset-bottom,0px))!important;
  border-radius:0 6px 6px 0!important;opacity:.9}}
/* Staging ribbon on phones: a slim strip on the tab bar's own top edge, over
   nothing that can be read (it used to float onto the footer wordmark). */
@media (max-width:759px){
  .envmark{inset-block-end:calc(64px + env(safe-area-inset-bottom,0px))!important;inset-inline-start:auto!important;inset-inline-end:0!important;
    padding:2px 8px 3px!important;font-size:.5625rem!important;border-radius:6px 0 0 0!important;opacity:.85}
  body.staging #feed,body.staging .screen{padding-block-end:18px}
}
/* Search tucks into an icon beside the bell once its bar has scrolled away. */
.mt-search{display:none}
@media (max-width:759px){
  body[data-screen="feed"].search-tucked .mt-search{display:grid}
}
/* The search bar scrolls away with the board under the fixed top bar and is
   there again at the top: seamless, no icon, nothing sticky covering the
   passes. (A sticky, folding version covered the heading when half-scrolled.) */
@media (max-width:759px){#feed .feedhead{position:static}}
/* Sign-up: one provider today, so one full-width "Continue with Google", the
   same as on sign-in (it was a lone square tile built for a row of three). */
#su-social{grid-template-columns:1fr!important}
#su-social .obtn{flex-direction:row!important;gap:10px!important;padding:13px 16px!important;font-size:.9375rem!important}
#su-social{margin-top:14px}
/* Phones, on the board: the list ends with its own short note; the full site
   footer (a second logo, links the tab bar already covers) is left out. */
@media (max-width:759px){body[data-screen="feed"] #sitefoot{display:none!important}
  body[data-screen="feed"] #feed .appfoot{display:block!important}}
/* Phones: pulling past the top used to stretch the page and show white above
   the plum bar. The page no longer bounces (Spare's own pull-to-refresh still
   works), and anything that does peek through at the top is plum. */
@media (max-width:759px){
  html,body{overscroll-behavior-y:none}
  html{background:linear-gradient(#2b1640 0 50%, var(--bg,#faf6f3) 50%)}
}
