/* ===========================================================================
   THE FEED — Infinite Pulls, phone first.

   This is the mockup, built. Not an interpretation of it: the words, the
   order of things, the gold-on-navy and the blue underline under the title
   are all from the picture Mike drew, and where I had a better idea I did
   not use it.

   WIDTH. Phones win. The look is chosen by screen size, so this sheet is
   written for a 393px phone and only widens the column past 520px -- there
   is no desktop redesign here on purpose, because the desktop keeps the UI
   it already has.
   =========================================================================== */

:root{
  --ink:#04070f;            /* the page, near black with blue in it */
  --panel:#0b1322;          /* a card, a strip, a panel */
  --panel-2:#111c31;        /* something sitting on a panel */
  --line:#1b3457;           /* every border in the design is this blue */
  --line-soft:#142440;
  --text:#e9f0fa;
  --dim:#8ba5c8;
  --dimmer:#5f7699;
  --blue:#3ea0ff;           /* the accent: titles, outlines, icons */
  --blue-soft:#6bb8ff;
  --blue-glow:#3ea0ff44;
  --gold:#ffc13d;           /* HYPE, usernames, the + button */
  --gold-soft:#ffd472;
  --green:#43d17f;          /* money and good news, never anything else */
  --nav-h:68px;
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--ink);color:var(--text);
  font:15px/1.45 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  -webkit-font-smoothing:antialiased;
  /* the raised SCAN ring rises above the bar, so the page owes it clearance
     on top of the bar's own height or the last post hides behind it */
  padding-bottom:calc(var(--nav-h) + 26px + env(safe-area-inset-bottom));
}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
img{display:block;max-width:100%}

/* ---- the top bar ------------------------------------------------------- */
/* THE BELL. On means on: the slash is only drawn when notifications are
   off, and it is gold when they are on, so the button is never ambiguous
   about which way it will go when tapped. */
.bell{position:relative}
.bell .slash{position:absolute;inset:0;margin:auto;width:40%;height:40%;stroke:#ff8888}
.bell.on svg{stroke:var(--gold)}
.bell.on .slash{display:none}
.bell[disabled]{opacity:.45}
.bell-said{
  grid-column:1/-1;margin-top:6px;text-align:center;
  font:700 11px/1.4 system-ui,sans-serif;color:var(--muted,#7b8aa3);
}
.bell-said.bad{color:#ff8888}
.bell-said.good{color:var(--green)}

/* the whole top block travels as one */
.stickytop{position:sticky;top:0;z-index:40}

.topbar{
  display:grid;grid-template-columns:44px 1fr auto;align-items:center;gap:10px;
  padding:calc(10px + env(safe-area-inset-top)) 12px 10px;
  background:#04070fe8;backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line-soft);
}
.topbar .mark{width:44px;height:44px;border-radius:11px;object-fit:contain}
.topbar h1{
  margin:0;text-align:center;font:800 15px/1 system-ui,sans-serif;
  letter-spacing:.20em;text-transform:uppercase;color:var(--text);
  padding-bottom:9px;position:relative;
}
/* the blue rule under the title, exactly as drawn -- short, centered, glowing */
.topbar h1::after{
  content:'';position:absolute;left:50%;bottom:0;transform:translateX(-50%);
  width:64%;max-width:190px;height:2px;border-radius:2px;
  background:linear-gradient(90deg,transparent,var(--blue),transparent);
  box-shadow:0 0 10px var(--blue-glow);
}
/* THE BUILD STAMP. There is no room for it on the same line as the title --
   INFINITE PULLS very nearly fills its column on a phone, and anything put
   beside it shoves the wordmark off center, which is not the design. So it
   sits on the row BELOW, at the end of the blue rule, where that space is
   already empty at every width. Never moves the title, never reaches the
   buttons. */
/* A badge on the corner of the logo tile. White, full strength, and big
   enough to read without leaning in -- which is the only thing it is for.
   The wrapper is exactly the 44px grid cell the logo already occupied, so
   nothing on the row moves. */
.markwrap{position:relative;display:block;width:44px;height:44px}
.ver{
  position:absolute;right:-7px;bottom:-5px;
  padding:2px 4px;border-radius:6px;
  background:#04070f;border:1px solid var(--line);
  font:800 10.5px/1 ui-monospace,SFMono-Regular,Menlo,monospace;
  letter-spacing:.02em;color:#ffffff;opacity:1;
  white-space:nowrap;pointer-events:none;
}
.topbar .tools{display:flex;gap:8px}

/* ---- the menu sheet ----------------------------------------------------
   Comes up from the bottom, near the thumb and near the button that opened
   it. The feed dims but stays visible, so it reads as something on top of
   the page rather than a page you were sent to. */
/* ---- A BUTTON IS NEVER A THING YOU ZOOM ------------------------------
   The old app has carried `button,a{touch-action:manipulation}` since the
   beginning. This stylesheet is a second one and never got it, so on the
   feed every control still answered a double tap the way iOS answers one on
   a paragraph: by zooming the page in.

   That is exactly what happened on NICE. The panel takes 620ms to fly the
   card away, nothing looks like it happened in the first instant, so the
   natural thing is to tap again -- and two taps on the same spot is the
   gesture for zoom. The screen zoomed, with no obvious way back out.

   This turns the double tap off ON CONTROLS ONLY. Pinch to zoom still
   works everywhere, and double tapping a card PHOTO still zooms it, which
   on an app full of pictures of cards is a feature and not a bug. */
button,a{touch-action:manipulation}

.sheet-wrap{position:fixed;inset:0;z-index:60;display:grid;align-items:end}
.sheet-wrap[hidden]{display:none}
.sheet-dim{position:absolute;inset:0;background:#00000099;backdrop-filter:blur(2px)}
.sheet{
  position:relative;background:var(--panel);border-top:1px solid var(--line);
  border-radius:18px 18px 0 0;padding:14px 14px calc(16px + env(safe-area-inset-bottom));
  box-shadow:0 -18px 40px #0009;
}
.sheet-top{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:0 2px 10px}
.sheet-top b{font:800 14px/1.3 system-ui,sans-serif;color:var(--text);min-width:0}
.sheet-top b small{display:block;font:600 12px/1.4 system-ui,sans-serif;color:var(--muted,#7b8aa3);margin-top:2px}
.sheet-x{
  flex:none;width:38px;height:38px;border-radius:50%;display:grid;place-items:center;
  color:var(--muted,#7b8aa3);font:800 22px/1 system-ui,sans-serif;background:var(--panel-2);
}
.sheet-rows{display:grid;gap:8px}
.sheet-rows a,.sheet-rows button{
  display:flex;align-items:center;gap:11px;width:100%;min-height:50px;padding:0 14px;
  border-radius:12px;border:1px solid var(--line);background:var(--panel-2);
  color:var(--text);text-decoration:none;
  font:800 12.5px/1 system-ui,sans-serif;letter-spacing:.06em;
}
.sheet-rows svg{width:17px;height:17px;stroke:var(--blue);fill:none;stroke-width:2;flex:none}
.sheet-rows .go{border-color:var(--gold);color:var(--gold)}
.sheet-rows .go svg{stroke:var(--gold)}
.sheet-rows .out{color:#ff8888;border-color:#ff888855}
.sheet-rows .out svg{stroke:#ff8888}

/* ---- THE THREE TILES ---------------------------------------------------
   The menu used to be eight full-width bars that all looked identical while
   doing three unrelated things. The three you actually open the menu for sit
   side by side now: one glance takes all three, and they stop competing with
   My Account and Sign Out, which are a different kind of thing.

   Square-ish rather than tall, so the row costs about the height of two of
   the old bars while carrying three destinations. */
.sheet-rows .tiles{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:8px;
}
.sheet-rows .tiles .tile{
  /* these override the long-row rules above, which are flex and 50px tall */
  display:grid;
  grid-template-rows:auto auto;
  justify-items:center;
  align-content:center;
  gap:7px;
  position:relative;
  width:100%;
  min-height:84px;
  padding:12px 6px;
  border-radius:12px;
  border:1px solid var(--line);
  background:var(--panel-2);
  color:var(--text);
  text-decoration:none;
  font:800 10.5px/1.15 system-ui,sans-serif;
  letter-spacing:.05em;
  text-align:center;
}
.sheet-rows .tiles .tile svg{width:21px;height:21px;stroke:var(--blue)}
.sheet-rows .tiles .tile span{display:block;max-width:100%}
.sheet-rows .tiles .tile:active{transform:translateY(1px)}

/* WITH NEWS IT GOES GOLD, and the count rides on the corner rather than in
   the label -- a label that grows by three characters when something arrives
   is a label that wraps on one tile and not the others. */
.sheet-rows .tiles .tile.has-news{border-color:var(--gold);color:var(--gold)}
.sheet-rows .tiles .tile.has-news svg{stroke:var(--gold)}
.tile-n{
  position:absolute;top:-7px;right:-5px;
  min-width:20px;height:20px;padding:0 5px;
  border-radius:999px;
  background:var(--gold);color:#04070f;
  font:800 11px/20px system-ui,sans-serif;letter-spacing:0;
  font-style:normal;
  border:2px solid var(--panel);
}

/* THE SECOND ROW IN THE SHOP SHEET is a step quieter than the first. Those
   three are real pages worth keeping a link to, but nobody opens this sheet
   to read them -- and giving them the same weight as HOURS says they are
   the same kind of thing, which they are not. */
.sheet-rows .tiles--quiet .tile{
  min-height:74px;
  background:transparent;
  color:var(--dim);
}
.sheet-rows .tiles--quiet .tile svg{stroke:var(--dim);width:19px;height:19px}

/* AT THE NARROWEST, TIGHTEN THE TYPE -- DO NOT RESTACK.
   The first version of this dropped to two columns with the last tile full
   width. That reads fine for a row of three and badly for a row of six: the
   shop sheet became two-and-one twice over, and at 320px it came out TALLER
   than the seven plain rows it replaced. Three across holds at every width;
   the labels just need a little less room. */
@media (max-width:349px){
  .sheet-rows .tiles{gap:6px}
  .sheet-rows .tiles .tile{
    min-height:78px;
    padding:10px 3px;
    font-size:9px;
    letter-spacing:.02em;
  }
  .sheet-rows .tiles--quiet .tile{min-height:70px}
}

/* ---- search ------------------------------------------------------------
   Under the top bar, not over the whole screen. The feed stays visible
   behind it so nobody feels they have left the page, and there are two ways
   out of it before you count the back button. */
.searchwrap{
  background:#04070ff2;backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line-soft);
  padding:10px 12px 8px;
}
.searchwrap[hidden]{display:none}
.searchbar{display:grid;grid-template-columns:18px 1fr auto;gap:9px;align-items:center}
.searchbar .mag{width:18px;height:18px;stroke:var(--blue);fill:none;stroke-width:2}
/* 16px or iOS zooms the whole page the moment it is tapped */
#q{
  width:100%;min-height:44px;border-radius:10px;padding:0 12px;
  border:1px solid var(--line);background:var(--panel);color:var(--text);
  font:600 16px/1 system-ui,sans-serif;
}
#q::placeholder{color:var(--muted,#7b8aa3)}
.searchbar .cancel{
  color:var(--gold);font:800 11px/1 system-ui,sans-serif;letter-spacing:.08em;
  padding:10px 4px;min-height:44px;
}
/* Capped so the pinned block can never swallow the screen: the bar and the
   search field come to about 130px, which leaves the feed visible underneath
   even on a short phone. */
.results{margin-top:8px;max-height:54vh;overflow-y:auto;overscroll-behavior:contain;display:grid;gap:2px}
.res-group{
  font:800 8.5px/1 system-ui,sans-serif;letter-spacing:.13em;color:var(--blue);
  padding:10px 2px 5px;
}
.res{
  width:100%;display:grid;grid-template-columns:38px 1fr;gap:10px;align-items:center;
  padding:8px;border-radius:10px;text-align:left;text-decoration:none;color:inherit;
  border:1px solid transparent;
}
.res:hover,.res:focus-visible{background:var(--panel);border-color:var(--line)}
.res .pic{
  width:38px;height:38px;border-radius:9px;object-fit:cover;background:var(--panel-2);
  display:grid;place-items:center;
}
.res .pic.round{border-radius:50%}
.res b{display:block;font:800 13px/1.25 system-ui,sans-serif;color:var(--text)}
.res small{display:block;font:600 11px/1.3 system-ui,sans-serif;color:var(--muted,#7b8aa3);margin-top:2px}
.res .why{
  display:block;margin-top:3px;font:600 11px/1.35 system-ui,sans-serif;color:var(--gold);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.res-none{padding:14px 4px;color:var(--muted,#7b8aa3);font:600 12px/1.5 system-ui,sans-serif}
.res-none b{display:block;color:var(--text);font:800 13px/1.4 system-ui,sans-serif;margin-bottom:3px}

/* ---- what the feed is narrowed to ---- */
.chipbar{
  padding:8px 12px;
  background:#04070fe8;backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line-soft);
}
.chipbar[hidden]{display:none}
.chip{
  display:inline-flex;align-items:center;gap:8px;max-width:100%;
  border:1px solid var(--line);border-radius:999px;background:var(--panel);
  padding:7px 6px 7px 13px;font:700 12px/1 system-ui,sans-serif;color:var(--text);
}
.chip b{color:var(--gold);font-weight:800}
.chip .x{
  width:28px;height:28px;border-radius:50%;display:grid;place-items:center;
  color:var(--muted,#7b8aa3);font:800 15px/1 system-ui,sans-serif;flex:0 0 auto;
}
.chip .x:hover{color:var(--text);background:var(--panel-2)}
.iconbtn{
  width:40px;height:40px;border-radius:50%;display:grid;place-items:center;
  background:var(--panel);border:1px solid var(--line);position:relative;
}
.iconbtn svg{width:19px;height:19px;stroke:var(--text);fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.iconbtn .pip{
  position:absolute;top:5px;right:6px;width:8px;height:8px;border-radius:50%;
  background:var(--gold);box-shadow:0 0 7px #ffc13daa;
}

/* ---- a post ------------------------------------------------------------ */
.feed{max-width:520px;margin:0 auto}
.post{padding:0 0 6px;margin-bottom:10px;border-bottom:1px solid var(--line-soft)}

.post-top{display:flex;align-items:center;gap:9px;padding:12px 11px 10px}
.avatar{
  width:44px;height:44px;border-radius:50%;flex:none;object-fit:cover;
  border:2px solid var(--gold);background:var(--panel-2);
}
.who{min-width:0;flex:1;overflow:hidden}
/* Both of these are ONE line. A shop name that wraps pushes the picture
   down the screen and makes every post a different height, which is the
   fastest way to make a feed feel homemade. */
.who b,.who small{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.who b{font:700 15px/1.2 system-ui,sans-serif;color:var(--gold)}
.who small{font-size:11.5px;color:var(--dim)}
/* THE SHOP IS NOT ONE OF THE COLLECTORS. Everybody's name is gold; Jeff's is
   the accent blue, which is the color the rest of the app already uses for
   "this belongs to Infinite Pulls itself". The pinned welcome post has read
   blue since it was built -- this is the same rule reaching the shelf posts
   too, so one account never shows up in two colors depending on which of its
   posts you happen to be looking at. Color is the only difference: it still
   sits in the same place, at the same size, and taps like any other name. */
.who-btn.is-shop b,
.caption b.is-shop{color:var(--blue)}
/* THE BOLT AND THE STAR ARE GONE. They were two hardcoded characters on
   every post header -- decoration that represented nothing about the person
   or the card -- and this stylesheet hid them below 410px because, in its own
   words, "the name and the FOLLOW button are the ones doing work". Something
   you are willing to hide on most phones because it is not doing work is
   something you can delete. Infinite Original arriving next to them settled
   it: one real badge and two fake ones an inch apart. */
.follow,.post-drop{
  flex:none;padding:7px 11px;border-radius:999px;white-space:nowrap;
  border:1.5px solid var(--blue);color:var(--blue);
  font:800 11.5px/1 system-ui,sans-serif;letter-spacing:.06em;
}
/* Same shape as FOLLOW because it sits in the same corner, but never the
   same class: one of these follows somebody and the other deletes a
   photograph. */
.post-drop{border-color:var(--line);color:var(--dim)}
.post-drop:disabled{opacity:.5}

/* ---- ONE POST, PINNED, BECAUSE SOMEBODY FOLLOWED A LINK TO IT ----------
   Marked out so a stranger arriving from Facebook can tell what they came
   for from the feed that carries on underneath it -- otherwise the post
   they followed is just the first of a hundred and they never know they
   found it. */
.pinned-post{border-bottom:1px solid var(--line);margin-bottom:6px}
.pinned-head{
  display:flex;align-items:center;gap:8px;padding:12px 14px 4px;
  font:800 10.5px/1 system-ui,sans-serif;letter-spacing:.14em;color:var(--gold);
}
.pinned-head svg{width:15px;height:15px;fill:none;stroke:var(--gold);stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;flex:none}
.pinned-more{
  display:block;text-align:center;padding:14px;text-decoration:none;
  font:800 11.5px/1 system-ui,sans-serif;letter-spacing:.1em;color:var(--blue);
}

/* ---- taken off the feed, with the way back still on screen -------------
   The post collapses rather than vanishing. REMOVE on something you own
   reads as "delete" whatever the button says, and the cheapest way to be
   believed is to leave the undo where they are already looking. */
.post.gone-from-feed > *:not(.undo-strip){display:none}
.post.gone-from-feed{padding:0}
.undo-strip{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:14px 14px;margin:0;
  border-top:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft);
  background:var(--panel-2,#0e1726);
}
.undo-strip span{font:500 13px/1.4 system-ui,sans-serif;color:var(--dim)}
.undo-strip button{
  flex:none;padding:8px 14px;border-radius:999px;cursor:pointer;
  background:none;border:1.5px solid var(--gold);color:var(--gold);
  font:800 11.5px/1 system-ui,sans-serif;letter-spacing:.08em;
}
.undo-strip button:disabled{opacity:.5}
.follow.on{background:#3ea0ff1a}
/* FOLLOW (not yet following) reads as the thing you can do, not as a state */
.follow:not(.on){border-color:var(--gold);color:var(--gold)}

/* What is left where somebody's cards were, and the way back. */
.gone{
  margin:0 0 10px;padding:13px 14px;border-radius:12px;
  border:1px solid var(--line);background:var(--panel);
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  font:600 13px/1.4 system-ui,sans-serif;color:var(--muted,#7b8aa3);
}
.gone > span{min-width:0}
.gone b{color:var(--text);font-weight:800}
.gone button{
  flex:none;min-height:38px;padding:0 14px;border-radius:999px;
  border:1.5px solid var(--gold);color:var(--gold);
  font:800 11px/1 system-ui,sans-serif;letter-spacing:.08em;
}

/* ---- the picture, and the sideways swipe through a card's photos -------- */
.frame{
  position:relative;background:#000;overflow:hidden;
  border-top:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft);
}
.rail{
  display:flex;overflow-x:auto;scroll-snap-type:x mandatory;
  scrollbar-width:none;-ms-overflow-style:none;
  -webkit-overflow-scrolling:touch;
  /* SAY WHICH WAY THIS ONE GOES. Left the browser to guess, a drag that
     starts a few degrees off horizontal is read as a page scroll and the
     strip never moves. pan-y stays on the list so a scroll that starts on
     a picture still scrolls the feed. */
  touch-action:pan-x pan-y;
  overscroll-behavior-x:contain;
}
.rail::-webkit-scrollbar{display:none}
.rail figure{margin:0;flex:0 0 100%;scroll-snap-align:center;background:#000}
/* Posts are not all the same shape -- a staged card is 4:5, Jeff's welcome
   picture is square, a selfie is whatever the phone gave us. The frame takes
   the tallest and letterboxes the rest rather than cropping, because the
   thing people put in the corner of a picture is usually the point of it. */
.rail figure img{width:100%;height:100%;object-fit:contain;display:block}
.frame[data-shape="portrait"] .rail figure{aspect-ratio:4/5}
.frame[data-shape="square"]   .rail figure{aspect-ratio:1/1}
/* "auto" is for a picture that is not a card -- Jeff's welcome art is 0.758,
   taller than the 4:5 frame, and forcing it into one would put bars down
   both sides of the first thing anybody ever sees. */
.frame[data-shape="auto"] .rail figure{aspect-ratio:auto}
.frame[data-shape="auto"] .rail figure img{height:auto}

.count{
  position:absolute;top:10px;right:10px;z-index:2;
  padding:5px 11px;border-radius:999px;background:#000000b0;
  border:1px solid var(--line);font:700 12px/1 system-ui,sans-serif;color:var(--text);
  backdrop-filter:blur(6px);
}
/* .hint is gone -- see the note in feed.js. The arrows are the affordance. */
.pips{
  position:absolute;left:0;right:0;bottom:10px;z-index:2;
  display:flex;justify-content:center;gap:6px;pointer-events:none;
}
/* TAPPABLE, not just an indicator. If a swipe will not work -- on a desktop
   it never could, there is nothing to swipe with -- the pips are a way
   through the strip that needs no gesture at all. */
.pips{pointer-events:none}
.pips i{
  width:6px;height:6px;border-radius:50%;background:#ffffff55;transition:background .2s;
  pointer-events:auto;cursor:pointer;border:0;padding:0;
  /* the dot is 6px; the thing you have to hit is 22px */
  box-sizing:content-box;border:8px solid transparent;background-clip:padding-box;
  margin:-8px;
}
.pips i.on{background:var(--gold);box-shadow:0 0 7px #ffc13d99;background-clip:padding-box}

/* ---- AND ARROWS, because a gesture is not a guarantee ------------------
   A strip you can only move by dragging is a strip that does not move at
   all on a desktop, and on a phone it depends on the browser agreeing with
   you about which way your thumb went. These do not care. */
.nudge{
  position:absolute;top:50%;transform:translateY(-50%);z-index:3;
  width:38px;height:38px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:#000000a8;border:1px solid var(--line);backdrop-filter:blur(6px);
  cursor:pointer;padding:0;transition:opacity .2s;
}
.nudge svg{width:20px;height:20px;fill:none;stroke:#fff;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round}
.nudge.prev{left:8px}
.nudge.next{right:8px}
.nudge[hidden]{display:none}
.nudge:disabled{opacity:.28;cursor:default}

/* SPECIFICITY, NOT AN OVERSIGHT. A bare [hidden]{display:none} is (0,0,0)
   and loses to .hint{display:flex} at (0,1,0), so a strip of one picture
   would keep its pips and its SWIPE prompt. Said here at equal weight. */
.count[hidden],.pips[hidden]{display:none}

/* ---- your own photos: the add tile, and taking one back ----------------- */
/* The last slide on your own card. It is a slide and not a button somewhere
   else on the page, so the empty space where a second picture would go is
   the thing that asks for one. */
.addpic{display:flex;align-items:stretch;justify-content:stretch;background:#0b0b0d}
.addpic button{
  flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;
  width:100%;margin:16px;padding:18px;cursor:pointer;
  color:var(--text);font:inherit;text-align:center;
  /* INSET, so the dashes read as an empty space waiting for something and
     not as the frame's own edge. Flush to the sides they looked like a
     border somebody had left switched on. */
  background:#ffffff05;border:1px dashed #ffffff33;border-radius:14px;
}
.addpic button:active{background:#ffffff08}
.addpic .plus{
  display:flex;align-items:center;justify-content:center;
  width:54px;height:54px;border-radius:50%;
  background:#ffffff10;border:1px solid var(--line);
  font:300 30px/1 system-ui,sans-serif;color:var(--gold);
}
.addpic b{font:800 12px/1.3 system-ui,sans-serif;letter-spacing:.14em;color:var(--text)}
.addpic small{font:500 11px/1.45 system-ui,sans-serif;color:var(--dim);max-width:19ch}
.addpic .say{
  font:700 11px/1.3 system-ui,sans-serif;letter-spacing:.06em;color:var(--gold);
  padding:5px 10px;border-radius:999px;background:#ffc13d1a;
}
.addpic .say[hidden]{display:none}
.frame[data-busy] .addpic button{opacity:.6;pointer-events:none}

/* Small, in the corner, and only on pictures you put there yourself. */
.dropx{
  position:absolute;top:8px;left:8px;z-index:3;
  width:30px;height:30px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:#000000b8;border:1px solid var(--line);backdrop-filter:blur(6px);
  color:#fff;font:400 19px/1 system-ui,sans-serif;cursor:pointer;
}
.dropx:disabled{opacity:.45}
.rail figure{position:relative}

/* ---- HYPE / COMMENT / SHARE / WISHLIST --------------------------------- */
/* AS MANY EQUAL COLUMNS AS THERE ARE BUTTONS, worked out by the grid rather
   than written down. This was repeat(4,1fr) with a separate rule saying 3
   for photo posts -- two numbers to keep in step with the markup, and the
   moment a shop post dropped its COMMENT button it sat in a four-column grid
   with a hole where the fourth used to be. */
.acts{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;
  align-items:center;padding:12px 4px 6px}
/* A photo post has three, not four: you cannot put somebody else's
   photograph on your wish list. */
/* .acts.is-photo no longer needs a column count -- the grid counts. */
/* A photograph is whatever shape the phone gave it, so the frame takes its
   height from the picture rather than pressing a face into a card. */
.post.is-photo .frame{background:#000}
.post.is-photo .rail figure{aspect-ratio:auto}
.post.is-photo .rail figure img{height:auto;object-fit:contain}
.act{
  display:flex;flex-direction:column;align-items:center;gap:5px;
  font:800 11px/1 system-ui,sans-serif;letter-spacing:.09em;color:var(--blue);
  padding:4px 0;position:relative;
}
.act + .act::before{
  content:'';position:absolute;left:0;top:14%;height:72%;width:1px;background:var(--line-soft);
}
.act svg{width:24px;height:24px;stroke:var(--blue);fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
/* HYPE is the one that is gold, drawn in a ring, with its number under it */
/* The name and the face are buttons now, but they have to look exactly like
   the text and picture they were -- a tappable thing in a feed header does
   not need a border to explain itself. */
.avatar-btn{padding:0;border:0;background:none;display:block;flex:none;border-radius:50%}
.who-btn{
  padding:0;border:0;background:none;text-align:left;min-width:0;
  font:inherit;color:inherit;display:block;
}
.avatar-btn:active,.who-btn:active{opacity:.6}

.act.hype{color:var(--gold);flex-direction:row;gap:10px}
.act.hype .ring{
  width:44px;height:44px;border-radius:50%;display:grid;place-items:center;
  /* THE COLDEST RING IS THE QUIETEST ONE. It used to be the brightest of
     the three, which had the whole scale running backwards: a card nobody
     had marked glowed harder than one forty people had. */
  border:2px solid #ffc13d77;box-shadow:inset 0 0 12px #ffc13d14;
  /* NOT hidden: past twenty the fire is bigger than the ring and is meant
     to sit over the edge of it. A circle that clips it is a circle winning
     an argument nobody wanted it to have. */
  overflow:visible;
}
/* The drawn flame, up from 22px. At 22 it sat in the middle of a 44px ring
   reading as a droplet rather than a flame -- the shape only becomes a
   flame once it is big enough to show its own notch. */
.act.hype svg{stroke:none;fill:var(--gold);width:33px;height:33px}
.act.hype .n{display:block;font:800 15px/1.1 system-ui,sans-serif;color:var(--text)}
.act.hype .lbl{font:800 11px/1 system-ui,sans-serif;letter-spacing:.09em;color:var(--gold)}

/* THE BLUE WAS AN ACCIDENT. This rule exists for WISHLIST -- a bookmark
   that fills in blue once it is saved -- and it was catching the flame on
   the way past, so marking a card HEAT turned the fire cold. Heat has its
   own marked state below, and it gets warmer, not bluer. */
.act.on:not(.hype) svg{fill:var(--blue);stroke:var(--blue)}

/* ---- HOT, AND BLAZING --------------------------------------------------
   Past twenty the real fire emoji takes over from the drawn flame, big
   enough to fill the ring and lean over it. Past fifty the picture does not
   change again -- a second emoji would read as clutter. The ring runs hotter
   and the number goes gold instead, which says "look at this one" without
   putting another thing on the screen. */
.act.hype .emoji{
  font-style:normal;line-height:1;
  /* the emoji's own glyph carries padding, so the box has to be bigger than
     the space it is meant to fill */
  font-size:31px;
  /* most fire emoji sit high in their box; this lands it on the middle of
     the ring rather than a couple of pixels above it */
  transform:translateY(1px);
}
.act.hype[data-level="2"] .ring{
  border-color:#ff8c3a77;
  box-shadow:0 0 18px #ff6a0040,inset 0 0 14px #ff6a001f;
}
.act.hype[data-level="3"] .emoji{font-size:35px}
.act.hype[data-level="3"] .ring{
  border-color:#ff5a1a99;
  box-shadow:0 0 24px #ff4d0066,inset 0 0 16px #ff4d0026;
}
.act.hype[data-level="3"] .n{color:var(--gold)}

/* ---- MARKED: THE LIGHT COMES OUT OF IT ---------------------------------
   This used to put a translucent gold WASH inside the circle, which is the
   opposite of what marking something should feel like: the ground behind
   the fire went pale, the fire lost its contrast against it, and tapping
   HEAT made the flame look DULLER than it did before you touched it.

   So nothing is laid over the top any more. The inside stays dark, the ring
   throws its glow outward, and the thing that actually lights up is the
   fire itself -- a drop-shadow follows the shape of the flame rather than
   filling the box around it, and it grows a hair.

   THESE RULES COME LAST ON PURPOSE. `.act.hype.on .ring` and
   `.act.hype[data-level="3"] .ring` carry identical specificity -- three
   classes and an element either way, since an attribute selector counts as
   a class -- so the tie is broken by source order and nothing else. Sitting
   above the level rules, as it used to, the marked state quietly lost every
   argument about the ring's shadow. */
.act.hype.on .ring{
  background:transparent;
  border-color:var(--gold);
  box-shadow:0 0 22px #ffc13d66;      /* outward only -- no inset, no wash */
}
.act.hype.on .emoji{
  transform:translateY(1px) scale(1.06);
  filter:drop-shadow(0 0 6px #ff7a00) drop-shadow(0 0 13px #ff4d0088);
}
.act.hype[data-level="3"].on .emoji{transform:translateY(1px) scale(1.06)}
.act.hype.on svg{filter:drop-shadow(0 0 6px #ffc13dcc)}
.act.hype.on .lbl{color:#ffd47a}
@media (prefers-reduced-motion:reduce){
  .act.hype.on .emoji{transform:translateY(1px)}
}

.caption{padding:6px 13px 2px;font-size:14px;line-height:1.45}
.caption b{color:var(--gold);font-weight:700}

/* ---- CARD PULSE --------------------------------------------------------- */
.snap{
  margin:11px 12px 0;border:1px solid var(--line);border-radius:12px;
  background:var(--panel);overflow:hidden;
}
.snap-head{display:flex;align-items:center;gap:10px;width:100%;padding:11px 12px;text-align:left}
.snap-head .ic{
  width:30px;height:30px;border-radius:8px;display:grid;place-items:center;
  background:#3ea0ff1f;border:1px solid var(--line);flex:none;
}
.snap-head .ic svg{width:16px;height:16px;stroke:var(--blue);fill:none;stroke-width:2}
.snap-head b{flex:1;font:800 12.5px/1 system-ui,sans-serif;letter-spacing:.13em;color:var(--text)}
/* The head is the whole hit target, so it gets the press state rather than
   some inner span -- a 44px row that moves under the thumb. */
.snap-head:active{background:#ffffff08}
.snap-head .chev{width:16px;height:16px;stroke:var(--dim);fill:none;stroke-width:2.4;
  transition:transform .22s}
.snap.shut .snap-head .chev{transform:rotate(180deg)}
.snap-body{padding:0 12px 12px}
.snap.shut .snap-body{display:none}

/* LABEL LEFT, VALUE RIGHT, one row each. The old single dot-separated line
   held three items comfortably and five badly: at 393px it wrapped, and a
   wrapped dot-line looks like a bug rather than a layout. Rows do not care
   how wide the phone is.
   The label column is fixed so every value starts at the same x -- a ragged
   left edge on five stacked values is the thing that makes a list look
   untidy, and it costs nothing to line them up. */
/* ITS OWN NAME, NOT `.fact`. That class was already taken -- it is the grid
   on the BACK of the card (ADDED, ORIGINAL VALUE, CURRENT VALUE) -- and the
   two collided in both directions. The back's rules sit lower in this file,
   so on every property both set they won the tie on source order and the
   label landed on top of its own value here; and on the one property only
   this rule set, a margin, it leaked the other way onto the card back.
   Neither was visible from reading either rule on its own. */
.pulse-rows{margin:0 0 11px;display:grid;gap:7px}
.pulse-row{display:flex;align-items:baseline;gap:10px}
.pulse-row dt{
  flex:none;width:74px;
  font:700 10.5px/1.35 system-ui,sans-serif;letter-spacing:.11em;
  text-transform:uppercase;color:var(--dimmer);
}
.pulse-row dd{
  margin:0;flex:1;min-width:0;
  font:800 12.5px/1.35 system-ui,sans-serif;letter-spacing:.03em;color:var(--text);
  overflow-wrap:anywhere;
}
.pulse-row dd.state{color:var(--green)}
.pulse-row dd.cond{color:var(--dim)}
.pulse-row dd.price{color:var(--green);font-size:13.5px}

/* The buttons live inside CARD PULSE now, under a hairline that says the
   facts stopped and the places to go started. */
.pills{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;
  padding-top:11px;border-top:1px solid var(--line-soft)}
/* Anchors now, not buttons -- a destination somebody can see before they
   commit to it, and a long-press that offers a new tab. */
.pill{text-decoration:none;
  display:flex;align-items:center;justify-content:center;gap:6px;
  min-height:44px;padding:0 6px;border-radius:11px;
  border:1px solid var(--line);background:var(--panel);
  font:800 9.5px/1.1 system-ui,sans-serif;letter-spacing:.01em;color:var(--text);
  text-align:center;
}
/* One line each. "SOLD LISTINGS" is the one that decides the size at 393px --
   three pills across a phone leaves about 84px of text room per pill. */
.pill span{white-space:nowrap}
.pill svg{width:14px;height:14px;stroke:var(--blue);fill:none;stroke-width:2;flex:none}

/* PRESSED, NOT ANIMATED. Two of these three navigate away the instant they
   are tapped, so anything with a run-up never finishes -- and that is the
   wrong thing to want anyway. On a phone there is no hover, so the only job
   here is to confirm the tap landed, which has to happen in the same moment
   the thumb touches glass. Down is instant; the way back up is the part
   allowed to take a moment, and only ever gets seen on SOLD LISTINGS, which
   opens a new tab and leaves the page where it was.
   `transform` and `background` only: both composite, neither reflows a grid
   of three that sits inside every card post on the screen. */
.pill{
  -webkit-tap-highlight-color:transparent;
  transition:transform .18s cubic-bezier(.2,.8,.3,1), background-color .18s, border-color .18s;
}
.pill:active{
  transform:scale(.955);
  background:var(--panel-2);border-color:var(--blue);
  transition-duration:0s;            /* down now, up later */
}
.pill:active svg{stroke:var(--blue-soft)}
@media (prefers-reduced-motion:reduce){
  .pill{transition:background-color .18s,border-color .18s}
  .pill:active{transform:none}
}

/* THE ONE THAT LEADS TO MONEY. It used to be a panel-colored row with a
   blue icon -- the same weight as everything around it, so the only action
   on the post that ends in a purchase looked like one more link. Gold now,
   which is the color this design already reserves for the things you act on
   (HYPE, the + button, a name), while the three research pills above it stay
   blue and quiet. Same side margins and corner radius as CARD PULSE, and the
   same 30px icon chip in its header, so it reads as the next row of one
   design rather than a component from somewhere else.
   The tint is a wash, not a fill: a solid gold bar under every shop post
   would shout over the photograph, which is the thing people came for. */
.nearby{text-decoration:none;
  display:flex;align-items:center;gap:11px;margin:9px 12px 4px;
  min-height:52px;padding:8px 12px;border-radius:12px;
  border:1px solid #ffc13d40;
  background:linear-gradient(100deg,#ffc13d1a,#ffc13d0d 55%,#ffc13d05);
  width:calc(100% - 24px);text-align:left;
  -webkit-tap-highlight-color:transparent;
  transition:transform .18s cubic-bezier(.2,.8,.3,1), background-color .18s, border-color .18s;
}
.nearby .ic{
  width:30px;height:30px;border-radius:8px;display:grid;place-items:center;
  background:#ffc13d1f;border:1px solid #ffc13d3d;flex:none;
}
.nearby .ic svg{width:18px;height:18px;stroke:var(--gold);fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
/* The label had a second line under it saying what was on the other side of
   the tap. It went: the row already says "at the shop", and a subtitle that
   restates the obvious costs a line of height on every shop post. */
.nearby .txt{flex:1;min-width:0;display:block}
.nearby .txt b{
  display:block;font:800 12.5px/1.25 system-ui,sans-serif;letter-spacing:.04em;
  color:var(--gold);
}
.nearby .chev{width:15px;height:15px;stroke:var(--gold);fill:none;stroke-width:2.4;flex:none;opacity:.75}
/* Pressed the same way the pills are, for the same reason: on a phone this
   is the only confirmation that the tap landed. */
.nearby:active{
  transform:scale(.985);
  background:#ffc13d26;border-color:var(--gold);
  transition-duration:0s;
}
@media (prefers-reduced-motion:reduce){
  .nearby{transition:background-color .18s,border-color .18s}
  .nearby:active{transform:none}
}

/* ---- the bottom bar ---------------------------------------------------- */
.nav{
  position:fixed;left:0;right:0;bottom:0;z-index:50;
  display:grid;grid-template-columns:repeat(5,1fr);align-items:end;
  height:calc(var(--nav-h) + env(safe-area-inset-bottom));
  padding:0 4px env(safe-area-inset-bottom);
  background:#04070ff2;backdrop-filter:blur(14px);border-top:1px solid var(--line-soft);
}
.nav a{
  display:grid;justify-items:center;gap:4px;padding:11px 2px 9px;
  font:800 9.5px/1 system-ui,sans-serif;letter-spacing:.05em;color:var(--dimmer);
}
/* every label stays on ONE line -- "SCAN A CARD" is the tight one at 393px,
   so it gets a hair less tracking rather than being allowed to wrap */
.nav a span{white-space:nowrap}
.nav a.scan span{font-size:9px;letter-spacing:.01em}
.nav a svg{width:21px;height:21px;stroke:var(--dimmer);fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
/* SIGNED IN LOOKS DIFFERENT FROM THE OTHER SIDE OF THE ROOM.
   The lines become your face. Same 21px box the other icons live in, so the
   row does not shift by a pixel, with a gold ring because at that size a
   small photo needs an edge to read as deliberate rather than as a smudge. */
/* YOUR FACE IS THE WHOLE ITEM.
   Signed in, the word MENU goes: a 52px photo of you does not need a caption,
   and dropping it is what makes room for the circle. Built the same way SCAN
   A CARD is -- a big round thing riding up over the top edge of the bar on a
   negative margin -- so the two read as a pair rather than as one oddity.
   A hair under the + at 56px, because the + is still the thing the app most
   wants you to press. */
/* The lines and the word are still THERE, just not shown: they hold the
   item at exactly the height of its four neighbours. Hide them outright and
   the item shrinks, the grid row resizes around it, and the SCAN A CARD
   circle beside it slides down five pixels -- which is what happened the
   first time. */
.nav a.isme svg{visibility:hidden}
/* :not(.navdot) ADDED, and it is load-bearing. This rule hides the word
   MENU when your face is showing, and it hid the notification count too --
   which sits in a span by necessity. The count reported itself present,
   displayed and correctly positioned, and simply did not paint. */
.nav a.isme span:not(.me):not(.navdot){visibility:hidden}
.me{
  box-sizing:border-box;
  width:52px;height:52px;
  /* LIFTED, NOT SHRUNK. A negative margin does nothing useful here: the nav
     bottom-aligns its items, so making the box shorter only moves its top
     down again and the circle ends up exactly where it started -- which is
     what the first two attempts at this did. position/top moves what you
     see without asking the layout's permission. */
  /* Out of the flow, so the circle can be any size it likes without the row
     resizing around it -- and sitting on the floor of the bar rather than
     riding over its top edge. */
  position:absolute;left:50%;transform:translateX(-50%);bottom:6px;
  border-radius:50%;overflow:hidden;
  display:grid;place-items:center;
  background:var(--ink,#04070f);border:3px solid var(--gold);
  box-shadow:0 0 18px #ffc13d55, 0 6px 18px #000a;
  font:800 17px/1 system-ui,sans-serif;color:var(--gold);letter-spacing:0;
}
.me[hidden]{display:none}
.me img{width:100%;height:100%;object-fit:cover;display:block}

.nav a.on{color:var(--gold)}
.nav a.on svg{stroke:var(--gold)}
.nav a.on::after{
  content:'';position:absolute;bottom:calc(4px + env(safe-area-inset-bottom));
  width:22px;height:3px;border-radius:3px;background:var(--gold);
}
.nav a{position:relative}
/* SCAN A CARD -- the raised gold ring in the middle, the one thing on the bar
   that is not a label with an icon over it */
.nav a.scan i{
  display:grid;place-items:center;width:56px;height:56px;border-radius:50%;
  margin-top:-26px;background:var(--ink);
  border:3px solid var(--gold);box-shadow:0 0 18px #ffc13d55,0 6px 18px #000a;
}
.nav a.scan i svg{width:26px;height:26px;stroke:var(--gold);stroke-width:2.6}
.nav a.scan{color:var(--gold)}
.nav a.scan::after{display:none}

/* ---- YOUR OWN BADGES, AT THE TOP OF YOUR FEED --------------------------
   Smaller than the profile's trophy case -- this is a reminder, not the
   display cabinet -- but still named, because the set shares one silhouette
   and a row of unlabelled medallions is a row of identical smudges. */
.mybadges{
  display:flex;gap:14px;padding:12px;margin:0 0 6px;
  overflow-x:auto;overscroll-behavior-x:contain;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;
  border-bottom:1px solid var(--line-soft);
}
.mybadges::-webkit-scrollbar{display:none}
.mb{
  flex:0 0 auto;width:76px;display:flex;flex-direction:column;align-items:center;gap:5px;
  text-align:center;text-decoration:none;color:inherit;
}
/* EARNED IS THE ONE THAT LOOKS DIFFERENT. Everything starts grey and dim;
   the ones you have actually got are full colour. That way the strip reads
   as a shelf with gaps rather than as eight things all shouting. */
.mb img{
  width:64px;height:64px;object-fit:contain;display:block;
  filter:grayscale(1);opacity:.42;
}
.mb.is-on img{filter:none;opacity:1}
.mb strong{color:var(--muted,#7b8aa3)}
.mb.is-on strong{color:var(--gold)}
.mb-bar{
  display:block;width:64px;height:3px;border-radius:3px;overflow:hidden;
  background:var(--panel-2);border:1px solid var(--line);
}
.mb-bar > span{display:block;height:100%;background:var(--gold);border-radius:3px}
.mb small{
  font:700 8px/1 ui-monospace,SFMono-Regular,Menlo,monospace;
  color:var(--muted,#7b8aa3);letter-spacing:.02em;
}
.mb-emoji{font-size:2.1rem;line-height:64px;height:64px;display:block}
.mb strong{
  font:800 8.5px/1.2 system-ui,sans-serif;letter-spacing:.02em;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  /* Two lines whether the name needs them or not, so every bar underneath
     sits on the same line. Clamping only sets a maximum; without a floor,
     GEM MINT TEN's bar rides higher than MONTHLY MOMENTUM's and the row
     looks assembled rather than designed. */
  min-height:2.4em;
}

/* ---- THE HOME PAGE RAILS, LIVING IN THE FEED ---------------------------
   They sit between posts, so they have to read as a different kind of thing
   from a card without shouting: a titled strip that scrolls sideways, edge
   to edge, against the feed's own background rather than in a card's frame. */
.rail-block{margin:6px 0 14px;padding:14px 0 4px;border-top:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft)}
.rail-block h2{
  margin:0 12px 10px;font:800 11px/1 system-ui,sans-serif;letter-spacing:.14em;
  text-transform:uppercase;color:var(--blue);
}
.rail-block .rail{
  display:flex;gap:10px;padding:0 12px 6px;overflow-x:auto;
  overscroll-behavior-x:contain;scrollbar-width:none;-webkit-overflow-scrolling:touch;
}
.rail-block .rail::-webkit-scrollbar{display:none}

.rail-video{
  flex:0 0 auto;width:168px;display:grid;gap:6px;padding:0;background:none;border:0;text-align:left;
}
.rail-thumb{
  position:relative;display:block;width:168px;aspect-ratio:16/9;border-radius:10px;overflow:hidden;
  background:var(--panel-2);border:1px solid var(--line);
}
.rail-thumb img,.rail-thumb iframe{width:100%;height:100%;object-fit:cover;display:block;border:0}
.rail-play{
  position:absolute;inset:0;margin:auto;width:38px;height:38px;border-radius:50%;
  display:grid;place-items:center;background:#04070fcc;border:1.5px solid var(--gold);
  color:var(--gold);font-size:13px;padding-left:2px;
}
.rail-video.is-playing{width:260px}
.rail-video.is-playing .rail-thumb{width:260px}
.rail-cap{
  font:700 11.5px/1.3 system-ui,sans-serif;color:var(--text);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}

.rail-mover{
  flex:0 0 auto;width:124px;display:grid;gap:4px;justify-items:center;text-align:center;
  padding:10px 8px;border-radius:12px;border:1px solid var(--line);background:var(--panel);
  text-decoration:none;color:inherit;
}
.rail-art{width:56px;height:78px;display:block;border-radius:4px;overflow:hidden;background:var(--panel-2)}
.rail-art img{width:100%;height:100%;object-fit:contain;display:block}
.rail-mover strong{
  font:800 11px/1.25 system-ui,sans-serif;color:var(--text);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.rail-move{font:800 12px/1 system-ui,sans-serif}
.rail-move.is-up{color:var(--green)}
.rail-move.is-down{color:#ff7a7a}
.rail-mover small{font:600 10px/1 system-ui,sans-serif;color:var(--muted,#7b8aa3)}
.rail-more{
  display:block;margin:4px 12px 0;padding:10px;border-radius:10px;text-align:center;
  border:1px solid var(--line);background:var(--panel-2);color:var(--gold);text-decoration:none;
  font:800 11px/1 system-ui,sans-serif;letter-spacing:.08em;
}

/* ---- states ------------------------------------------------------------ */
.msg{padding:40px 22px;text-align:center;color:var(--dim);font-size:14px}
.msg b{display:block;color:var(--text);margin-bottom:6px;font-size:15.5px}
.skel{padding:12px}
.skel .bar{height:14px;border-radius:7px;background:var(--panel-2);margin-bottom:10px}
.skel .box{aspect-ratio:4/5;border-radius:12px;background:var(--panel-2)}
@keyframes pulse{0%,100%{opacity:.55}50%{opacity:.95}}
.skel .bar,.skel .box{animation:pulse 1.4s ease-in-out infinite}

.end{padding:26px 18px 10px;text-align:center;color:var(--dimmer);
  font:800 11px/1 system-ui,sans-serif;letter-spacing:.16em;text-transform:uppercase}
.end::before,.end::after{content:'—';margin:0 8px;color:var(--line)}

@media (min-width:521px){
  .feed{border-left:1px solid var(--line-soft);border-right:1px solid var(--line-soft)}
}


/* ---- THE BACK OF THE CARD ----------------------------------------------
   Tap the picture and the post turns over. FEED-NEXT.md settled this as a
   flip in place rather than a separate screen -- the post keeps its header,
   its HYPE and its place in the scroll, so turning a card over never costs
   somebody their position in the feed.

   The face on the back is Infinite Pulls' own, not a reproduction of a
   Pokemon card back. */
/* THE FLIP, WITH NOTHING CLEVER LEFT IN IT.
   
   This has now been the suspect twice for a strip that would not swipe on a
   phone, so everything that could possibly be blamed has been taken out of
   the resting state:
   
     no transform-style:preserve-3d -- that put the photo strip inside a 3D
     rendering context, which a mobile browser hands to the compositor as
     one flattened layer;
     
     no backface-visibility -- which is a layer-promotion trigger in its own
     right, and was the only thing standing between the picture and a
     full-size .rear panel sitting on top of it;
     
     no transform on the front while it faces you.
   
   Instead the back is plainly `visibility:hidden` when it is not showing --
   which, unlike a hidden backface, is guaranteed not to be painted AND not
   to be hit-tested, so it cannot swallow a thumb. Both sides swap
   visibility at the halfway point of the turn, which is where the card is
   edge-on and neither is visible anyway.
   
   At rest, .side.front is now an ordinary static div with no transform, no
   backface and nothing composited. If the swipe still does not work on a
   phone, it is not this. */
.flip{position:relative}
.flip > .side{
  transition:transform .55s cubic-bezier(.3,.8,.3,1), visibility 0s linear .275s;
}
.flip > .side.rear{position:absolute;inset:0;transform:rotateY(180deg);visibility:hidden}
.frame.back .flip > .side.front{transform:rotateY(180deg);visibility:hidden}
.frame.back .flip > .side.rear{transform:rotateY(360deg);visibility:visible}
@media (prefers-reduced-motion:reduce){
  .flip > .side{transition:visibility 0s}
}

/* ---- THE PRICE CHART ----------------------------------------------------
   One series, so no legend box: the heading names it. Hairline grid a single
   shade off the surface, never dashed -- dashing reads as "projection" when
   it is only a grid. */
.chart{
  grid-column:1/-1;margin-top:4px;
  border:1px solid var(--line);border-radius:10px;background:var(--panel);
  padding:8px 8px 6px;
}
.chart-head{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  margin-bottom:2px;flex-wrap:wrap;
}
.chart-k{font:800 8.5px/1 system-ui,sans-serif;letter-spacing:.13em;color:var(--blue)}
.ranges{display:flex;gap:3px}
/* 28px tall so a thumb can hit one without hitting its neighbor. */
.rg{
  min-width:30px;min-height:28px;padding:0 7px;border-radius:7px;
  border:1px solid transparent;background:transparent;color:var(--dim);
  font:800 9px/1 system-ui,sans-serif;letter-spacing:.08em;cursor:pointer;
}
.rg.on{background:var(--ink);border-color:var(--line);color:var(--gold)}
.pchart{display:block;width:100%;height:auto;touch-action:pan-y}
.pchart .g{stroke:var(--line);stroke-width:1;shape-rendering:crispEdges}
.pchart .l{fill:none;stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.pchart .a{stroke:none;opacity:.14}
.pchart .cross{stroke:var(--dim);stroke-width:1}
.pchart .dot{stroke:var(--panel);stroke-width:2}
/* The line carries the direction, matching the arrow on the artwork so the
   two can never tell different stories. */
.pchart.up   .l,.pchart.up   .dot{stroke:var(--green)} .pchart.up   .a,.pchart.up   .dot{fill:var(--green)}
.pchart.down .l,.pchart.down .dot{stroke:#ff7a7a}      .pchart.down .a,.pchart.down .dot{fill:#ff7a7a}
.pchart.flat .l,.pchart.flat .dot{stroke:var(--gold)}  .pchart.flat .a,.pchart.flat .dot{fill:var(--gold)}
/* Axis text wears text tokens, never the series color. */
.pchart text{
  font:700 8px/1 system-ui,sans-serif;fill:var(--dim);
  font-variant-numeric:tabular-nums;
}
.readout{
  margin:2px 0 0;min-height:12px;text-align:center;
  font:700 10px/1.2 system-ui,sans-serif;color:var(--dim);
  font-variant-numeric:tabular-nums;
}

/* ---- EDIT MY CARD INFO -------------------------------------------------
   Sits under LOOK UP NOW and matches it, because they are the two things
   you can do about a card you are reading -- go and check it, or fix it. */
.btn-edit{
  display:flex;align-items:center;justify-content:center;gap:7px;
  width:100%;margin-top:7px;min-height:44px;padding:10px;
  border-radius:10px;background:var(--panel);border:1px solid var(--line);
  color:var(--gold);font:800 10.5px/1 system-ui,sans-serif;letter-spacing:.12em;
  cursor:pointer;
}
.btn-edit svg{width:15px;height:15px;stroke:var(--gold);fill:none;stroke-width:2}

/* ---- THE EDIT BOX -------------------------------------------------------
   Over the card rather than instead of it: nothing navigates, so there is
   nowhere to get lost. Bottom-anchored on a phone, where a thumb is, and it
   scrolls inside itself so a long grade ladder never pushes the SAVE button
   off the bottom of the screen. */
.ce-wrap{position:fixed;inset:0;z-index:60;display:flex;align-items:flex-end;justify-content:center}
.ce-dim{position:absolute;inset:0;background:#000000bf;backdrop-filter:blur(2px)}
.ce-box{
  position:relative;width:100%;max-width:460px;max-height:88vh;overflow:auto;
  -webkit-overflow-scrolling:touch;
  background:var(--ink);border:1px solid var(--line);
  border-radius:16px 16px 0 0;padding:14px 14px calc(14px + env(safe-area-inset-bottom));
  box-shadow:0 -10px 40px #000000d9;
}
@media (min-width:560px){
  .ce-wrap{align-items:center}
  .ce-box{border-radius:16px}
}
.ce-head{display:flex;align-items:center;justify-content:space-between;gap:10px}
.ce-head b{font:800 11px/1 system-ui,sans-serif;letter-spacing:.16em;color:var(--gold)}
.ce-x{
  /* 44px. It is the way out, and a way out you have to aim at is not one. */
  width:44px;height:44px;border-radius:50%;border:1px solid var(--line);
  background:var(--panel);color:var(--dim);font-size:15px;line-height:1;cursor:pointer;
}
.ce-name{margin:6px 0 12px;font:800 15px/1.25 system-ui,sans-serif;color:var(--text);overflow-wrap:anywhere}
.ce-lab{
  display:block;margin:12px 0 5px;
  font:800 8.5px/1 system-ui,sans-serif;letter-spacing:.13em;color:var(--blue);
}
.ce-sel,.ce-in{
  width:100%;box-sizing:border-box;min-height:44px;padding:10px 11px;
  border-radius:10px;border:1px solid var(--line);background:var(--panel);
  color:var(--text);font:700 14px/1.2 system-ui,sans-serif;
  /* 14px or bigger, or iOS zooms the whole page in when it is focused and
     the box ends up half off the screen. */
}
.ce-two{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.ce-two .ce-lab{margin-top:0}
.ce-tabs{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.ce-tab{
  min-height:40px;border-radius:9px;border:1px solid var(--line);
  background:var(--panel);color:var(--dim);cursor:pointer;
  font:800 10px/1 system-ui,sans-serif;letter-spacing:.13em;
}
.ce-tab.on{background:var(--gold);border-color:var(--gold);color:#12203a}
.ce-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.ce-chip{
  min-height:40px;padding:0 12px;border-radius:999px;
  border:1px solid var(--line);background:var(--panel);color:var(--dim);
  font:700 12px/1 system-ui,sans-serif;cursor:pointer;
}
.ce-chip.on{background:var(--gold);border-color:var(--gold);color:#12203a;font-weight:800}
.ce-hint{margin:6px 0 0;font:400 11px/1.4 system-ui,sans-serif;color:var(--dim)}
.ce-qty{display:grid;grid-template-columns:48px 1fr 48px;gap:8px;align-items:center}
.ce-step{
  height:44px;border-radius:10px;border:1px solid var(--line);
  background:var(--panel);color:var(--gold);font-size:18px;cursor:pointer;
}
.ce-num{text-align:center;font-variant-numeric:tabular-nums}
.ce-err{
  margin:10px 0 0;padding:9px 10px;border-radius:9px;
  background:#3a1414;border:1px solid #7a2a2a;color:#ffb4b4;
  font:700 12px/1.35 system-ui,sans-serif;
}
.ce-actions{display:grid;grid-template-columns:1fr 1.4fr;gap:8px;margin-top:16px}
.ce-cancel,.ce-save{
  min-height:46px;border-radius:11px;cursor:pointer;
  font:800 11px/1 system-ui,sans-serif;letter-spacing:.13em;
}
.ce-cancel{background:transparent;border:1px solid var(--line);color:var(--dim)}
.ce-save{background:var(--gold);border:1px solid var(--gold);color:#12203a}
.ce-save[disabled]{opacity:.6}

/* ---- THE WAY OUT --------------------------------------------------------
   This was a small dark chip in the corner and it was missed every time --
   the habit it lost to was the phone's own back button, which used to leave
   the feed and lose the post underneath. The back button is handled in
   feed.js now; this is the other half. Face up it stays a quiet chip,
   because CARD STORY is an invitation and does not need to shout. Face
   DOWN it becomes a solid gold bar spanning the frame: the one obviously
   pressable thing on the panel, where a thumb already rests. */
.turn{
  position:absolute;right:10px;bottom:10px;z-index:3;
  display:flex;align-items:center;justify-content:center;gap:6px;
  padding:8px 12px;border-radius:999px;
  background:#000000b3;border:1px solid var(--line);backdrop-filter:blur(6px);
  font:800 10px/1 system-ui,sans-serif;letter-spacing:.10em;color:var(--gold);
}
.frame.back .turn{
  left:10px;right:10px;bottom:10px;
  padding:12px;border-radius:10px;
  background:var(--gold);border-color:var(--gold);color:#12203a;
  letter-spacing:.14em;font-size:11px;
  box-shadow:0 6px 18px #000000a6;
}
.frame.back .turn svg{stroke:#12203a}
/* The panel scrolls, and the bar sits on top of it -- so the last row needs
   somewhere to go or the bar covers it. */
.frame.back .rear{padding-bottom:58px}
.turn svg{width:14px;height:14px;stroke:var(--gold);fill:none;stroke-width:2.2}

.rear{
  background:var(--ink);display:grid;grid-template-columns:38% 1fr;gap:10px;padding:12px;
  /* start, not stretch: the back is shorter than the front, and stretched rows
     left a dead band across the top. And it scrolls rather than clips, because
     a long timeline must not cut itself off inside a fixed-height frame. */
  align-content:start;overflow:auto;-webkit-overflow-scrolling:touch;
}
.rear .cardhead{grid-column:1/-1;text-align:center;padding-bottom:4px}

/* ---- THE GRADING LABEL --------------------------------------------------
   A graded card is read off its label, and the label is black on white --
   the only white thing anywhere in this app, which is exactly why it reads
   as a slab the moment it appears. Drawn from the card's own data: no
   grader's logo, no wordmark, no copy of anybody's label artwork.

   Left-aligned, because a label is read, not admired. */
.rear .cardhead.is-slab{text-align:left}
.slab{
  display:grid;grid-template-columns:1fr auto;gap:10px;align-items:stretch;
  background:#f6f5f1;color:#11131a;
  border:1px solid #cfcdc6;border-radius:8px;
  padding:9px 10px;
  /* The faint lift a slab has sitting on a dark surface. */
  box-shadow:0 2px 10px #0009, inset 0 1px 0 #ffffff;
}
.slab-id{min-width:0;display:flex;flex-direction:column;justify-content:center;gap:3px}
.slab-id b{
  font:800 13px/1.2 system-ui,sans-serif;letter-spacing:.01em;color:#11131a;
  /* A long name plus a finish plus a number really is wide. It wraps; it
     never gets truncated, because the number is the half that identifies
     the card and the end of the line is exactly where it lives. */
  overflow-wrap:anywhere;text-transform:uppercase;
}
.slab-id span{font:700 9.5px/1.2 system-ui,sans-serif;letter-spacing:.07em;color:#5b5e69}

/* The grade, in the corner where a label puts it. */
.slab-grade{
  flex:0 0 auto;display:flex;flex-direction:column;align-items:center;justify-content:center;
  min-width:62px;padding:4px 8px;
  border-left:1px solid #cfcdc6;
}
.slab-co{font:800 9px/1 system-ui,sans-serif;letter-spacing:.16em;color:#11131a}
.slab-grade b{
  font:800 27px/1 system-ui,sans-serif;letter-spacing:-.02em;color:#11131a;margin-top:2px;
  /* Proportional figures: tabular gives every digit the width of a 0, which
     makes a number this size look loose. */
}
.slab-grade i{
  font:800 7px/1 system-ui,sans-serif;font-style:normal;letter-spacing:.11em;
  color:#5b5e69;margin-top:3px;text-align:center;
}

/* The certificate, along the bottom of the label the way it is printed. */
.slab-cert{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  margin-top:5px;padding:8px 10px;min-height:40px;box-sizing:border-box;
  background:#e9e8e3;border:1px solid #cfcdc6;border-radius:7px;
  color:#11131a;text-decoration:none;
  font:800 10px/1 system-ui,sans-serif;letter-spacing:.09em;
  font-variant-numeric:tabular-nums;
}
.slab-cert i{font:800 8px/1 system-ui,sans-serif;font-style:normal;letter-spacing:.09em;color:#3a5fa8}
/* SGC and BGS publish no page for one certificate, so there is nothing to
   tap. It says the number and stops, rather than looking like a link that
   does not work. */
.slab-cert.is-plain{color:#3d404a}
.rear .cardhead.is-slab .eyebrow{text-align:center;margin-top:6px}
/* The card's own name leads. It is the biggest thing on the back because it
   is the one question the back exists to answer.

   :not(.is-slab) IS LOAD-BEARING. A graded card's header is a white label
   with its own type, and this rule at (0,2,1) was quietly beating the
   label's own (0,1,1) rules -- painting the card name and the big grade
   number in the dark theme's light-on-dark color, on white. Both went
   nearly invisible, and the grade came out at 15px instead of 27. */
.rear .cardhead:not(.is-slab) b{
  display:block;font:800 15px/1.25 system-ui,sans-serif;color:var(--text);
  letter-spacing:.01em;
  /* A long name plus a finish plus a number is genuinely wide. Wrapping is
     right; truncating the number off the end is not. */
  overflow-wrap:anywhere;
}
.rear .eyebrow{
  display:block;margin-top:3px;
  font:800 9.5px/1 system-ui,sans-serif;letter-spacing:.16em;color:var(--gold);
  padding-bottom:2px;
}
/* THE CARD ITSELF. It used to be the Infinite Pulls logo, which told you
   which app you were in -- something you already knew -- on the one panel
   with room for the card you were actually looking at. The branded panel is
   still here as the fallback for a row with no artwork, under .no-art. */
.backface{
  border-radius:10px;border:1px solid var(--line);overflow:hidden;position:relative;
  /* CARD-SHAPED, AND NOT A PIXEL TALLER. As a plain grid item it stretched to
     whatever the column of fact tiles came to -- which with the chart added
     was a tall black slab with a small card floating in the middle of it.
     A card is 5:7; the panel is 5:7; the art fills it. */
  aspect-ratio:5/7;align-self:start;
  background:
    radial-gradient(120% 90% at 50% 38%, #16325c 0%, #0a162b 55%, #050b16 100%);
  display:grid;place-items:center;
}
.backface::before{
  content:'';position:absolute;inset:0;
  background:
    repeating-linear-gradient(90deg,transparent 0 26px,#3ea0ff14 26px 27px),
    repeating-linear-gradient(0deg,transparent 0 26px,#3ea0ff14 26px 27px);
}
/* The card fills the panel; the logo never did. object-fit:contain so a
   sideways promo is letterboxed rather than cropped through the middle. */
.backface .art{
  position:relative;width:100%;height:100%;
  object-fit:contain;border-radius:8px;display:block;
}
/* Only the fallback panel keeps the old grid-and-glow treatment. On real
   artwork it showed through the card's own borders. */
.backface:not(.no-art){background:#05080f}
.backface:not(.no-art)::before{content:none}
.backface img{width:62%;opacity:.92;position:relative}

/* ---- THE MOVEMENT, READ BEFORE ANY OF THE TEXT -------------------------
   Up the LEFT in green, down the RIGHT in red. The position is doing the
   work: which side it sits on says the direction before the arrow or the
   number is read at all, which is the whole point of putting it here rather
   than in another labelled tile. A gradient scrim behind it keeps it legible
   over artwork of any brightness -- a white border card would otherwise eat
   a green arrow whole. */
/* Scoped under .backface deliberately: the older `.backface span` rule is
   (0,1,1) and quietly outranked a bare `.mv` (0,1,0), which dropped
   position:absolute and left the arrow centered in the panel instead of
   hugging its edge -- and the edge is the whole point. */
.backface .mv{
  /* 52%, measured rather than guessed: at 38% the figure overflowed its own
     scrim at +18.4%, and a card that doubles prints +100.0%, which is the
     width this has to hold. */
  position:absolute;top:0;bottom:0;width:52%;z-index:2;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  padding:4px 3px;pointer-events:none;
}
.backface .mv.up{left:0;background:linear-gradient(90deg,#000000d9 0%,#000000a6 55%,transparent 100%)}
.backface .mv.down{right:0;background:linear-gradient(270deg,#000000d9 0%,#000000a6 55%,transparent 100%)}
.backface .mv svg{width:26px;height:26px;fill:currentColor;stroke:none;filter:drop-shadow(0 1px 3px #000)}
.backface .mv b{
  font:800 12px/1 system-ui,sans-serif;letter-spacing:0;text-shadow:0 1px 3px #000;
  /* Never broken across two lines: "+18." above "4%" is not a number. */
  white-space:nowrap;
}
.backface .mv i{
  font:800 6.5px/1.2 system-ui,sans-serif;font-style:normal;letter-spacing:.09em;
  color:#ffffffb3;text-align:center;text-shadow:0 1px 3px #000;
}
.backface .mv.up{color:var(--green)}
.backface .mv.down{color:#ff7a7a}

/* STEADY IS AN ANSWER, not a blank. Across the bottom rather than up a side,
   because there is no direction to point and a horizontal bar reads as
   "level" on sight. */
.backface .mv.steady{
  top:auto;bottom:0;left:0;right:0;width:auto;
  flex-direction:row;gap:7px;justify-content:center;align-items:baseline;
  padding:5px 6px;color:var(--gold);
  background:linear-gradient(0deg,#000000e0 0%,#000000a6 70%,transparent 100%);
}
.backface .mv.steady b{font-size:11px;letter-spacing:.14em}
.backface .mv.steady i{font-size:6.5px}
.backface span{
  position:relative;font:800 10px/1.3 system-ui,sans-serif;letter-spacing:.14em;
  color:var(--blue-soft);text-align:center;padding:0 8px;
}

.facts{display:grid;gap:7px;align-content:start;min-width:0}
.fact{
  border:1px solid var(--line);border-radius:10px;background:var(--panel);
  padding:8px 10px;display:grid;grid-template-columns:22px 1fr;gap:9px;align-items:center;
}
.fact svg{width:16px;height:16px;stroke:var(--blue);fill:none;stroke-width:2}
.fact .k{display:block;font:800 8.5px/1 system-ui,sans-serif;letter-spacing:.13em;color:var(--blue)}
.fact .v{display:block;font:800 14px/1.2 system-ui,sans-serif;color:var(--text);margin-top:3px}
/* The converted figure is deliberately quieter than the quote it follows --
   the euro is the real number; the dollar is our estimate of it. */
.fact .fx{font-weight:700;font-size:11px;color:var(--dim);letter-spacing:0}
.fact .v.up{color:var(--green)}
.fact .v.down{color:#ff7a7a}

.tline{grid-column:1/-1;display:grid;gap:0;margin-top:2px}
.tline li{
  list-style:none;position:relative;padding:0 0 12px 20px;
  border-left:1px solid var(--line);margin-left:5px;
}
.tline li:last-child{border-left-color:transparent;padding-bottom:0}
.tline li::before{
  content:'';position:absolute;left:-5px;top:2px;width:9px;height:9px;border-radius:50%;
  background:var(--ink);border:2px solid var(--gold);
}
.tline .d{font:800 8.5px/1 system-ui,sans-serif;letter-spacing:.1em;color:var(--gold)}
.tline .t{display:block;font:700 12px/1.3 system-ui,sans-serif;color:var(--text);margin-top:3px}
.tline .s{display:block;font-size:11.5px;color:var(--dim);margin-top:1px}
.tline .quiet{color:var(--dimmer);font-size:11.5px;padding-left:20px}


/* ---- Jeff's welcome post ------------------------------------------------
   Not a card, so it carries none of a card's furniture: no HYPE count it
   did not earn, no price, no snapshot, no card story. Just the picture and
   who it is from. The picture points at the + in the bar below it, which is
   a real button, so this post has a genuine way forward. */
.post.tutorial .post-top b{color:var(--blue)}
.post.tutorial .frame{border-top:0}
.pin{
  display:inline-flex;align-items:center;gap:5px;margin-left:6px;
  padding:3px 8px;border-radius:999px;background:#3ea0ff1f;border:1px solid var(--line);
  font:800 9px/1 system-ui,sans-serif;letter-spacing:.10em;color:var(--blue);
}


/* ---- MY HISTORY, the written story ------------------------------------
   The panel that turns a list of what you own into a scrapbook. Read-only
   on somebody else's card; on your own it opens an editor in place. */
.story{
  grid-column:1/-1;margin-top:2px;
  border:1px solid var(--line);border-radius:10px;background:var(--panel);
  padding:10px 12px;
}
.story .k{
  display:flex;align-items:center;gap:7px;
  font:800 8.5px/1 system-ui,sans-serif;letter-spacing:.13em;color:var(--blue);
}
.story .k svg{width:14px;height:14px;stroke:var(--blue);fill:none;stroke-width:2}
.story p{margin:7px 0 0;font-size:13px;line-height:1.5;color:var(--text);white-space:pre-wrap}
.story p.empty{color:var(--dimmer);font-style:italic}
.story textarea{
  width:100%;margin-top:8px;min-height:96px;resize:vertical;
  background:var(--ink);color:var(--text);border:1px solid var(--line);
  border-radius:9px;padding:9px 10px;
  font:400 16px/1.5 system-ui,sans-serif;   /* 16px or iOS zooms the page */
}
.story-btns{display:flex;gap:8px;margin-top:9px}
.story-btns button{
  flex:1;min-height:42px;border-radius:10px;
  font:800 11px/1 system-ui,sans-serif;letter-spacing:.08em;
}
.btn-save{background:linear-gradient(135deg,var(--gold-soft),var(--gold));color:#2a1d05}
.btn-cancel{border:1px solid var(--line);background:var(--panel-2);color:var(--dim)}
/* PRICE WHEN ADDED holds two markets, so it gets the full width rather than
   squeezing TCGplayer and Cardmarket into a half-column each. */
.fact.wide{grid-column:1/-1}
.fact .mkt{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin-top:4px}
.fact .mkt .m{
  font:800 8.5px/1 system-ui,sans-serif;letter-spacing:.1em;color:var(--muted,#7b8aa3);
  min-width:78px;
}
.fact .mkt .v{margin-top:0}
.fact .asof{
  font:600 9px/1 system-ui,sans-serif;color:var(--muted,#7b8aa3);opacity:.85;
}

/* Reads as a button, behaves as a link -- it leaves the feed for the lookup
   page, and a real link can be opened in a new tab or long-pressed. */
.btn-look{
  grid-column:1/-1;margin-top:2px;min-height:42px;border-radius:10px;
  border:1px solid var(--line);background:var(--panel-2);color:var(--gold);
  font:800 11px/1 system-ui,sans-serif;letter-spacing:.08em;text-decoration:none;
  display:flex;align-items:center;justify-content:center;gap:8px;
}
.btn-look svg{width:15px;height:15px;stroke:var(--gold);fill:none;stroke-width:2}

/* THIS COPY -- the card's own facts, full width under the back face.
   Full width and not a third column because a phone has no third column:
   at 393px the back is already a 38/62 split, and squeezing "1st Edition
   Holofoil" into half of the 62 wraps it to three lines. */
.spec{
  grid-column:1/-1;min-width:0;
  border:1px solid var(--line);border-radius:10px;background:var(--panel);
  padding:9px 10px;
}
.spec-head{
  display:flex;align-items:center;gap:7px;
  font:800 8.5px/1 system-ui,sans-serif;letter-spacing:.13em;color:var(--gold);
  margin-bottom:9px;
}
.spec-head svg{width:14px;height:14px;stroke:var(--gold);fill:none;stroke-width:2}
/* minmax(0,1fr), not 1fr: a grid track is min-content wide by default and
   refuses to shrink, so a long set name pushed the second column off the
   card instead of wrapping inside its own. */
.spec-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 10px}
.spec-row{min-width:0}
.spec-row.wide{grid-column:1/-1}
.spec-row .k{display:block;font:800 8px/1 system-ui,sans-serif;letter-spacing:.12em;color:var(--blue)}
.spec-row .v{
  display:block;font:800 12.5px/1.25 system-ui,sans-serif;color:var(--text);
  margin-top:3px;overflow-wrap:anywhere;
}
.sp-num{color:var(--dim);font-weight:700;margin-left:2px}
.sp-grade{color:var(--gold)}
.sp-raw{color:var(--dim)}
.sp-cert{color:var(--blue);text-decoration:none}
.sp-cert small{
  display:block;margin-top:2px;
  font:800 8.5px/1 system-ui,sans-serif;letter-spacing:.1em;color:var(--dim);
}
.spec-note{
  margin:10px 0 0;font:600 10.5px/1.45 system-ui,sans-serif;color:var(--muted,#7b8aa3);
}
.spec-note b{color:var(--text)}
/* Its own line under the note, not inside it: floated into the paragraph it
   broke the text around itself and read as a word in the middle of a
   sentence rather than the thing to tap. */
.sp-sold{
  display:flex;align-items:center;justify-content:center;gap:7px;
  min-height:38px;margin-top:9px;
  padding:0 10px;border-radius:9px;border:1px solid var(--line);background:var(--panel-2);
  color:var(--gold);text-decoration:none;
  font:800 10px/1 system-ui,sans-serif;letter-spacing:.09em;
}
.sp-sold svg{width:14px;height:14px;stroke:var(--gold);fill:none;stroke-width:2}

.btn-edit{
  margin-top:9px;width:100%;min-height:42px;border-radius:10px;
  border:1px solid var(--line);background:var(--panel-2);color:var(--gold);
  font:800 11px/1 system-ui,sans-serif;letter-spacing:.08em;
}
.said-ok{color:var(--green);font:800 11px/1 system-ui,sans-serif;margin-top:8px;display:block}
.said-no{color:#ff8888;font:800 11px/1 system-ui,sans-serif;margin-top:8px;display:block}

/* A row with no card behind it -- the welcome card -- has nothing to put on
   a wish list, so the button says so by being unavailable rather than by
   doing nothing when tapped. */
.act:disabled{opacity:.35}

/* ---- COMMENTS ------------------------------------------------------------
   Closed on every post until somebody asks for it, which is the rule the
   whole feed is built on: a card is a picture first and a conversation
   second, and a feed where every post carries its comments open is a feed
   you scroll past three times as slowly to see the same six cards. */
/* ---- THE COMMENTS ------------------------------------------------------
   THIS IS THE ONE LIGHT THING IN A DARK APP, and that is the point. It was
   the same near-black as the post above it with nothing but a hairline
   between them, so an open thread read as more post -- and three people
   answering each other under one card was genuinely hard to follow, because
   nothing on screen said where one voice stopped and the next began.

   White says "this part is people talking" without a word of explanation,
   the way a sheet of paper does. Names, faces and replies all read at a
   glance because black-on-white is what a lifetime of reading has trained
   for, and the dark app around it becomes the frame.

   HOW IT FLIPS. Rather than rewriting the thirty-odd rules underneath, the
   container redefines the palette for its own subtree. Every rule in here
   that already said var(--text) or var(--panel) keeps saying it and simply
   means something else inside this box. Anything that hard-codes a hex is
   listed further down and is the only thing that needed a second rule.

   The geometry is CARD PULSE's, deliberately: same side margins, same
   radius, same head with a 30px icon chip and a chevron. One design. */
.talk{
  --panel:#ffffff;
  --panel-2:#f1f5f9;
  --line:#d7e0ea;
  --line-soft:#e8eef4;
  --text:#0d1725;
  --dim:#55677e;
  /* #7c8da0 was the obvious light-mode dimmer and it measured 3.4:1 against
     white on 11px timestamps -- under the 4.5 a small font needs, and the
     whole reason for this box is that people could not read it. 4.9. */
  --dimmer:#627386;
  --blue:#0f62c4;           /* #3ea0ff is a dark-background blue; on white
                               it fails contrast against body text */
  --blue-soft:#3f8ae0;
  --gold:#8a5a06;           /* and gold on white is simply not readable */
  --green:#12794a;

  margin:11px 12px 0;border:1px solid var(--line);border-radius:12px;
  background:var(--panel);overflow:hidden;color:var(--text);
}
.talk[hidden]{display:none}

/* The head. Same measurements as .snap-head so the two boxes on one post
   read as one family, in this box's own colors. */
.talk-head{
  display:flex;align-items:center;gap:10px;width:100%;padding:11px 12px;
  text-align:left;background:var(--panel-2);border-bottom:1px solid var(--line-soft);
}
.talk-head .ic{
  width:30px;height:30px;border-radius:8px;display:grid;place-items:center;
  background:#0f62c414;border:1px solid var(--line);flex:none;
}
.talk-head .ic svg{width:16px;height:16px;stroke:var(--blue);fill:none;stroke-width:2}
.talk-head b{font:800 12.5px/1 system-ui,sans-serif;letter-spacing:.13em;color:var(--text)}
/* The count sits beside the word, not out at the end -- at the end it reads
   as a separate control rather than as part of the label. */
.talk-n{
  font:800 11px/1 system-ui,sans-serif;font-style:normal;color:var(--blue);
  background:#0f62c414;border:1px solid #0f62c433;border-radius:999px;padding:4px 7px;
}
.talk-n[hidden]{display:none}
/* THE CHEVRON POINTS UP, because this one closes rather than folds -- and
   the glyph already points up, which is why there is no rotation here. Card
   Pulse turns it 180 to say "shut, tap to open"; this box has no shut state
   to get into, so it only ever means the one thing. Pushed to the right edge
   by the margin, so the head reads left to right: what this is, how much of
   it there is, and the way out. */
.talk-head .chev{margin-left:auto;width:16px;height:16px;stroke:var(--dim);
  fill:none;stroke-width:2.4}
.talk-head:active{background:#e3eaf2}

.talk-body{padding:12px 12px 14px}

/* ---- the hard-coded colors, which the palette swap cannot reach ---- */
/* Each of these was picked to sit on near-black and is too pale on paper. */
.talk .say-note.bad{color:#b3261e}
.talk .clink.drop:active{color:#b3261e}
.talk .cwho .tag{color:var(--blue);border-color:#0f62c44d;background:#0f62c414}
.talk .send{border-color:var(--blue);background:#0f62c414;color:var(--blue)}
.talk .send:active{background:#0f62c426}
.talk .chrt.on svg{stroke:#d63864;fill:#d63864}
.talk .chrt.on .hn{color:#d63864}
/* A white input on a white panel is not a box. It needs the tint. */
.talk .say input{background:var(--panel-2)}
/* The face had a dark placeholder behind it while it loaded. */
.talk .cface{background:#e8eef4}

/* ---- a name in a thread is a destination ---- */
/* It looks like the thing it is, and it has a press state, because a word
   that navigates and never acknowledges the tap reads as broken text. */
.talk .cname,.talk .cface[data-open-person]{cursor:pointer}
.talk .cname{-webkit-tap-highlight-color:transparent}
.talk .cname:active{color:var(--blue-soft);text-decoration:underline}
.talk .cface[data-open-person]:active{opacity:.7}

/* THE TEN CHIPS. One row, sideways, and deliberately NOT wrapped: ten of
   these wrapped is four rows deep on a phone and pushes the next post off
   the screen to make room for something nobody has asked for yet.
   The last chip is cut off at the right edge on purpose -- a row that ends
   flush looks finished, and then nobody swipes it. */
.quick{
  display:flex;gap:8px;overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;
  padding-bottom:4px;margin-bottom:10px;
}
.quick::-webkit-scrollbar{display:none}
.quick{scrollbar-width:none}
.chip{
  flex:none;scroll-snap-align:start;
  min-height:40px;padding:0 14px;border-radius:999px;
  border:1px solid var(--line);background:var(--panel);
  font:800 12.5px/1 system-ui,sans-serif;color:var(--text);
  white-space:nowrap;-webkit-tap-highlight-color:transparent;
  transition:transform .18s cubic-bezier(.2,.8,.3,1), background-color .18s, border-color .18s, opacity .18s;
}
.chip:active{transform:scale(.94);background:var(--panel-2);border-color:var(--blue);transition-duration:0s}
/* Held down for a moment after a tap. The chips are big and close together,
   and the cost of a double tap is a duplicate comment in front of everybody. */
.chip:disabled{opacity:.45}

/* The box, and the thing that tells you why a comment did not post. */
.say{display:flex;gap:8px;align-items:stretch}
.say input{
  flex:1;min-width:0;min-height:46px;padding:0 13px;border-radius:12px;
  border:1px solid var(--line);background:var(--panel);color:var(--text);
  font:500 14px/1.2 system-ui,sans-serif;
}
.say input::placeholder{color:var(--dimmer)}
.say input:focus{outline:none;border-color:var(--blue)}
.send{
  flex:none;min-height:46px;padding:0 16px;border-radius:12px;
  border:1px solid var(--blue);background:#3ea0ff1f;color:var(--blue);
  font:800 12px/1 system-ui,sans-serif;letter-spacing:.09em;
  -webkit-tap-highlight-color:transparent;
}
.send:active{background:#3ea0ff33}

.say-note{margin:8px 2px 0;font:700 12px/1.4 system-ui,sans-serif}
.say-note.bad{color:#ff9d9d}
.say-note.ok{color:var(--green)}
.undo{
  margin-left:8px;padding:4px 10px;border-radius:8px;
  border:1px solid var(--line);background:var(--panel);
  font:800 11px/1 system-ui,sans-serif;letter-spacing:.09em;color:var(--blue);
}

/* Who you are replying to, and a way to stop. */
.replying{
  display:flex;align-items:center;gap:8px;margin-bottom:8px;
  padding:7px 10px;border-radius:10px;background:var(--panel);
  border:1px solid var(--line-soft);
  font:700 12px/1 system-ui,sans-serif;color:var(--dim);
}
/* ANY ELEMENT GIVEN A display RULE IGNORES THE BROWSER'S OWN [hidden], so
   both of the things here that are toggled with the attribute have to say so
   themselves. The stylesheet already does this three times over for the
   sheet, the search and the chip bar; these are the fourth and fifth, and
   both were briefly visible while their markup said hidden. */
.replying[hidden]{display:none}
.act .cn[hidden]{display:none}
.replying span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.replying .x{flex:none;color:var(--dim);font-size:19px;line-height:1;padding:0 4px}

/* ---- one comment ---- */
.said{margin-top:12px;display:grid;gap:12px}
.talk-empty{margin:2px;color:var(--dimmer);font:600 12.5px/1.5 system-ui,sans-serif}

.cmt{display:flex;gap:10px;align-items:flex-start}
/* ONE STEP IN, AND ONLY ONE. Replies to replies are filed against the same
   parent by the database, so this indent can never stack -- which is what
   keeps a thread readable at 393px instead of turning into a staircase. */
.cmt.is-reply{padding-left:34px}
.cface{
  flex:none;width:30px;height:30px;border-radius:50%;object-fit:cover;
  background:var(--panel-2);border:1px solid var(--line);
}
.cmt.is-reply .cface{width:25px;height:25px}
.cbody{flex:1;min-width:0}
.cwho{margin:0;display:flex;align-items:baseline;gap:7px;flex-wrap:wrap}
.cwho b{font:800 12.5px/1.3 system-ui,sans-serif;color:var(--gold)}
/* THE PERSON WHOSE POST IT IS. Their answer under their own card is not the
   same kind of thing as a stranger's, and the name is the only room on a
   phone to say so. */
.cwho b.is-owner{color:var(--blue)}
.cwho .tag{
  font:800 8.5px/1 system-ui,sans-serif;letter-spacing:.11em;color:var(--blue);
  border:1px solid #3ea0ff4d;border-radius:5px;padding:3px 5px;background:#3ea0ff14;
}
.cwho small{font:600 11px/1.3 system-ui,sans-serif;color:var(--dimmer)}
.ctext{margin:4px 0 0;font:500 13.5px/1.5 system-ui,sans-serif;color:var(--text);
  overflow-wrap:anywhere}

.cacts{display:flex;align-items:center;gap:14px;margin-top:6px}
.chrt{
  display:flex;align-items:center;gap:5px;
  -webkit-tap-highlight-color:transparent;
  transition:transform .18s cubic-bezier(.2,.8,.3,1);
}
.chrt:active{transform:scale(.88);transition-duration:0s}
.chrt svg{width:16px;height:16px;stroke:var(--dim);fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.chrt.on svg{stroke:#ff6b8a;fill:#ff6b8a}
.chrt .hn{font:800 11.5px/1 system-ui,sans-serif;color:var(--dim)}
.chrt.on .hn{color:#ff6b8a}
.clink{
  font:800 10.5px/1 system-ui,sans-serif;letter-spacing:.1em;color:var(--dim);
  -webkit-tap-highlight-color:transparent;
}
.clink:active{color:var(--blue)}
.clink.drop:active{color:#ff9d9d}

/* The number on the COMMENT icon. Hidden at zero rather than showing a 0 --
   "0 comments" is a fact nobody needs and it makes every quiet post look
   like it is reporting a failure. */
.act .cn{
  position:absolute;top:-2px;left:50%;margin-left:6px;
  min-width:17px;height:17px;padding:0 4px;border-radius:9px;
  display:grid;place-items:center;
  background:var(--blue);color:#03101b;
  font:800 10px/1 system-ui,sans-serif;letter-spacing:0;
}
@media (prefers-reduced-motion:reduce){
  .chip,.chrt{transition:background-color .18s,border-color .18s}
  .chip:active,.chrt:active{transform:none}
}

/* ---- INFINITE ORIGINAL 2026 ----------------------------------------------
   The badge sits beside a name, so it is sized against the name rather than
   against anything else: it reads as punctuation on the end of the word, not
   as a picture in its own right. Anything bigger and it becomes the thing
   you look at first, which is the wrong order -- the name is the subject. */
.vb{
  flex:none;width:15px;height:15px;display:inline-block;
  vertical-align:-2px;margin-left:4px;
}
.caption .vb,.cwho .vb{margin-left:3px}

/* The name, the badge and the line under it are ONE row that shares the
   width. The name never truncates -- it is the thing being identified -- and
   the tagline gives way, because a cut-off tagline is still readable as a
   tagline and a cut-off name is somebody else. */
.nameline{display:flex;align-items:center;gap:0;min-width:0}
.nameline > b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* The tagline sits where the post's subtitle was. It is the person's own
   words, so it does not get to look like one of the app's labels -- no caps,
   no letter-spacing, and a shade warmer than the subtitle it replaced so the
   difference is visible without being loud. */
.who small.tline{
  display:block;font:600 11.5px/1.3 system-ui,sans-serif;color:var(--dim);
  font-style:normal;letter-spacing:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* ---- the sheet ---- */
.sheet-rows .go.gold{
  border-color:#ffc13d5c;color:var(--gold);
  background:linear-gradient(100deg,#ffc13d1f,#ffc13d0d 60%,#ffc13d05);
  display:flex;align-items:center;gap:10px;
}
.sheet-rows .go.gold:active{background:#ffc13d2e;border-color:var(--gold)}
.sheet-rows .go.gold .vb{width:18px;height:18px;margin:0;vertical-align:0}

.badge-hero{
  display:flex;align-items:center;gap:14px;
  padding:14px;margin-bottom:10px;border-radius:14px;
  border:1px solid #ffc13d3d;
  background:linear-gradient(100deg,#ffc13d17,#ffc13d0a 60%,transparent);
}
.badge-hero img{flex:none;width:96px;height:96px}
.badge-hero.small img{width:64px;height:64px}
.badge-hero p{margin:0;font:500 13px/1.5 system-ui,sans-serif;color:var(--text)}
.badge-hero b{color:var(--gold)}

/* THE SENTENCE THAT KEEPS THE BADGE HONEST. Dim, but not so dim it reads as
   small print somebody is meant to skip -- it is the part that stops a gold
   star being mistaken for the shop vouching for a stranger. */
.sheet-note{
  margin:10px 2px 12px;font:500 12px/1.55 system-ui,sans-serif;color:var(--dim);
}
/* THE SHEET MAKES EVERY BUTTON A FULL-WIDTH ROW, which is right for a menu
   and wrong for the one button that sits beside a text box. `.sheet-rows a,
   .sheet-rows button { width:100% }` caught SAVE, so it started the flex row
   at the container's full width and squeezed the input down to a sliver --
   the form was there and typed into, it just had nowhere to be.
   Scoped back for this one form rather than weakening the menu rule. */
.sheet-rows .say{margin-top:4px;display:flex;gap:8px;align-items:stretch}
.sheet-rows .say input{flex:1 1 auto;min-width:0;width:auto}
.sheet-rows .say .send{width:auto;flex:0 0 auto;min-height:46px;padding:0 18px}
.sheet-rows .say-note{margin:8px 2px 0}

/* ---- THE NOTIFICATION COUNT -------------------------------------------
   CENTRED ON THE AVATAR'S CORNER, not offset from its left. The circle is
   52px centred in the nav item, so its 45-degree corner is 18px right of
   centre -- putting the badge's own centre there means a two-digit count
   and a three-digit one grow evenly either side instead of marching toward
   the edge of the screen.

   It is NOT inside .me: that element is overflow:hidden to keep the photo
   round, and anything in there gets its corner cut off. */
.navdot{
  position:absolute;
  bottom:41px;
  left:calc(50% + 17px);
  transform:translateX(-50%);
  min-width:20px;height:20px;
  padding:0 5px;
  border-radius:999px;
  background:var(--gold);
  color:#04070f;
  font:800 11px/20px system-ui,sans-serif;
  letter-spacing:0;
  text-align:center;
  border:2px solid #04070f;
  box-shadow:0 2px 8px #000a;
  pointer-events:none;
}
.navdot[hidden]{display:none}
/* The narrowest phones still in use put that circle 5px from the bezel, and
   a three-character count is nearly 40px wide -- which ran off the screen.
   Pulled in AND shrunk, because moving it alone was not enough. */
@media (max-width:340px){
  .navdot{
    left:calc(50% + 11px);
    min-width:18px;height:18px;
    padding:0 4px;
    border-width:1.5px;
    font-size:10px;line-height:18px;
  }
}

/* ---- THE LIST ---------------------------------------------------------
   Rows in the same sheet everything else uses, so the app still has one
   kind of pop-up. An unread row carries a gold edge; reading them does not
   make them vanish, because a list that empties itself the moment you look
   at it is a list you cannot go back to. */
.alert{
  display:grid;grid-template-columns:34px 1fr;gap:10px;align-items:start;
  width:100%;
  padding:11px 12px;
  border:0;border-radius:12px;
  background:transparent;
  color:inherit;font:inherit;text-align:left;
  cursor:pointer;
}
.alert + .alert{border-top:1px solid var(--line-soft)}
.alert.unread{background:#ffc13d12;border-left:3px solid var(--gold);padding-left:9px}
.alert .face{
  width:34px;height:34px;border-radius:50%;overflow:hidden;
  display:grid;place-items:center;
  background:#0d1420;border:1px solid var(--line-soft);
  font:800 13px/1 system-ui,sans-serif;color:var(--gold);
}
.alert .face img{width:100%;height:100%;object-fit:cover;display:block}
/* The app's own rows have no face to show. A gold mark rather than a blank
   circle or, worse, an initial belonging to nobody. */
.alert .face.is-app{background:#ffc13d1a;border-color:#ffc13d55}
.alert .face.is-app svg{width:18px;height:18px;fill:none;stroke:var(--gold);stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.alert .txt{min-width:0}
.alert .txt b{font-weight:800}
.alert .txt p{margin:0;font-size:13.5px;line-height:1.35}
.alert .txt small{display:block;margin-top:3px;font-size:11.5px;color:var(--dimmer)}
.alert .quote{
  margin-top:4px;
  font-size:12.5px;line-height:1.35;color:var(--dim);
  overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
}
.alert-empty{padding:26px 12px;text-align:center;color:var(--dimmer);font-size:13.5px;line-height:1.5}


/* ======================================================================
   INFINITE REWARDS + THE INFINITE DEX — the sheet.
   Built for a phone at 393px. Desktop only has to not look broken.
   ====================================================================== */

/* THE SHEET HAD NO CEILING.
   It grows to fit its rows, and .sheet-wrap is fixed with no scroll, so
   anything taller than the screen ran off the top with no way to reach it.
   Fifty-one cards is 17 rows. Notifications already had this at 40. */
.sheet{max-height:88dvh;display:flex;flex-direction:column;min-height:0}
.sheet-top{flex:none}
.sheet-rows{overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
  min-height:0;padding-bottom:2px;
  /* MAKING THIS SCROLL MADE IT CLIP. The notification count rides on the
     corner of its tile at top:-7px, which used to hang harmlessly over the
     sheet -- a scroll container cuts it off instead, and six pixels of the
     badge went missing. The padding gives the overhang somewhere to live and
     the matching negative margin puts everything back where it was, so no
     other sheet moves by a pixel. */
  padding-top:9px;margin-top:-9px}

/* ---- NOTHING TAPPABLE OVER THE BOTTOM BAR ------------------------------
   The sheet is z-index 60 and the nav is 50, so an open sheet covers the
   bar. Its last row therefore landed on top of whichever nav button you had
   just tapped -- and in the menu, the last row is SIGN OUT. Tap MENU at the
   bottom right, tap the same spot again to close it, and you signed out.
   The auth log said the button was pressed, and it was.

   This holds the bar's own height clear at the foot of every sheet, so no
   row can sit over a nav button again, and it closes the sheet when tapped,
   which makes MENU and COLLECTION behave like the toggles they look like.
   The sheet already carries 16px of bottom padding, so the strip only has
   to make up the rest. */
.sheet-foot{flex:none;height:calc(var(--nav-h) - 16px)}

/* ---- SIGN OUT ASKS TWICE ----------------------------------------------
   Belt and braces for the above: the one row in here that throws work away
   should not be a single tap, wherever it happens to land. */
.sheet-rows .out.armed{
  color:#ff5f5f;border-color:#ff5f5f;background:#ff5f5f1a;
}
.sheet-rows .out.armed svg{stroke:#ff5f5f}

/* ---- two collections, two tabs ---- */
.rwd-tabs{display:grid;grid-template-columns:repeat(3,1fr);gap:5px;margin:0 0 12px}
.sheet-rows .rwd-tab{
  display:block;width:100%;min-height:0;padding:9px 6px;gap:0;text-align:center;
  border-radius:10px;border:1px solid var(--line);background:var(--panel-2);
  font:800 10.5px/1.1 system-ui,sans-serif;letter-spacing:.07em;color:var(--dim);
}
.sheet-rows .rwd-tab i{
  display:block;margin-top:4px;font:800 11px/1 system-ui,sans-serif;
  font-style:normal;letter-spacing:.02em;color:var(--dimmer);
}
.sheet-rows .rwd-tab{font-size:10px;padding:9px 4px}
.sheet-rows .rwd-tab.is-on{border-color:var(--gold);background:#ffc13d14;color:var(--gold)}
.sheet-rows .rwd-tab.is-on i{color:var(--gold-soft)}
/* A prize actually waiting is the one thing on this sheet worth shouting
   about, so the tab says so even when you are looking at another one. */
.sheet-rows .rwd-tab.is-won i{color:var(--green)}

/* ---- how far along ---- */
.rwd-bar{height:4px;border-radius:3px;background:#ffffff14;overflow:hidden;margin:0 2px 12px}
.rwd-bar span{display:block;height:100%;background:var(--gold);border-radius:3px}

/* ---- the fifty ---- */
.rwd-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px 7px;margin-bottom:6px}

/* .sheet-rows styles every button as a 50px-tall row with side padding.
   These are cards with a caption, so all of that has to come back off. */
.sheet-rows .rwd{
  display:block;width:100%;min-height:0;padding:0;gap:0;
  border:0;background:none;text-align:center;
}
.rwd .shot{
  position:relative;display:block;aspect-ratio:5/7;border-radius:9px;overflow:hidden;
  border:1px solid var(--line);background:var(--panel-2);
}
.rwd .shot img{width:100%;height:100%;object-fit:cover;display:block}
.sheet-rows .rwd:active .shot{transform:scale(.97)}

/* The number alone told you nothing. What earns it is the reason to care. */
.rwd b{
  display:block;margin-top:5px;font:800 10px/1 system-ui,sans-serif;
  letter-spacing:.06em;color:var(--gold-soft);
}
.rwd small{
  margin-top:3px;font:700 8.5px/1.25 system-ui,sans-serif;letter-spacing:.02em;
  color:var(--dimmer);overflow:hidden;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
}
.rwd.off b{color:var(--dim)}

/* Locked. Not a blank slot -- you can see the shape of what is waiting,
   and nothing you could read off it. */
.rwd.off .shot img{filter:grayscale(1) brightness(.3) contrast(1.15);opacity:.62}
.rwd.off .shot{border-color:var(--line-soft)}
.rwd-lock{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none}
.rwd-lock svg{width:18px;height:18px;stroke:#ffffff5c;fill:none;stroke-width:2}

/* ---- how close you are, on a locked card ----
   Inside the artwork, along its bottom edge, so it is in the same place on
   every tile and adding it changed no tile's height. Only the 32 countable
   cards get one: a bar on "set your avatar" would sit at 0% while somebody
   is one tap from done. */
.rwd-prog{
  position:absolute;left:0;right:0;bottom:0;height:3px;
  background:#00000073;pointer-events:none;
}
.rwd-prog i{
  display:block;height:100%;background:var(--gold);
  box-shadow:0 0 6px #ffc13d66;
}
.rwd-prog-n{
  position:absolute;left:0;right:0;bottom:7px;pointer-events:none;
  font:800 8.5px/1 system-ui,sans-serif;letter-spacing:.03em;
  color:#ffd98a;text-align:center;text-shadow:0 1px 3px #000,0 0 6px #000;
}
/* The lock sits dead centre; nudge it up so the two never touch. */
.rwd.off .rwd-lock{align-items:center;padding-bottom:14px}

/* ---- the same thing on the opened card ---- */
/* THE RULE, UNDER THE LABEL. Quieter than the task line above it and set
   in sentence case, because it is a sentence -- the label shouts, this
   explains. Held to a readable measure rather than running the full width
   of a phone. */
.task-why{
  margin:6px auto 0;max-width:30em;
  font:400 12.5px/1.5 system-ui,sans-serif;color:var(--dim);
  text-align:center;text-transform:none;letter-spacing:0;
}

.rwd-open-prog{margin:14px auto 0;max-width:260px}
.rwd-open-prog .rwd-bar{margin:0 0 6px}
.rwd-open-n{
  margin:0;font:800 12px/1 system-ui,sans-serif;letter-spacing:.04em;
  color:var(--gold-soft);text-align:center;
}

/* ---- 51/50, on its own, because it is the prize ---- */
.rwd-secret{margin:16px 0 4px}
.sheet-rows .rwd.big{
  display:flex;align-items:center;gap:12px;text-align:left;
  padding:10px;border-radius:12px;border:1px solid #ffc13d55;background:#ffc13d0f;
}
.rwd.big .shot{flex:none;width:74px;border-radius:7px;border-color:#ffc13d44}
.rwd.big .txt{min-width:0}
.rwd.big .txt b{display:block;margin:0;font:800 13px/1.25 system-ui,sans-serif;
  color:var(--gold);letter-spacing:.03em}
.rwd.big .txt small{display:block;margin-top:4px;font:600 11.5px/1.4 system-ui,sans-serif;
  color:var(--dim);letter-spacing:0;-webkit-line-clamp:none}
.rwd.big.off{border-color:var(--line);background:var(--panel-2)}
.rwd.big.off .txt b{color:var(--dim)}
.rwd.big.off .shot img{filter:grayscale(1) brightness(.3);opacity:.62}

/* ---- the Dex ---- */
.dex-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px 8px}
.dex-one{text-align:center;min-width:0}
/* THE PLINTH.
   A circle cropped out of the card art was the wrong container twice over:
   it cut the character's ears off at the top and it made twenty-five
   different drawings sit at twenty-five different sizes. These are cutouts
   on transparent backgrounds, so the tile can hold the whole character and
   let it float -- rounded square rather than a circle, because a circle
   fights a shape that has corners. */
.dex-face{
  position:relative;width:100%;aspect-ratio:1;border-radius:14px;overflow:hidden;
  border:1px solid var(--line);background:var(--panel-2);
  display:grid;place-items:center;
}
.dex-face img{
  position:relative;width:100%;height:100%;object-fit:contain;display:block;
  padding:7%;box-sizing:border-box;
}
/* FOUND: it lights up. The glow sits behind the character rather than on
   the tile edge, so the Pullkin is the thing that looks switched on. */
.dex-one.on .dex-face{
  border-color:#ffc13d66;
  background:radial-gradient(circle at 50% 62%, #ffc13d26 0%, #ffc13d0d 46%, transparent 72%),
             var(--panel-2);
}
.dex-one.on .dex-face img{filter:drop-shadow(0 3px 5px #0009)}

/* NOT FOUND: a silhouette, the way a Dex has always done it. Grayscale left
   it looking like a bad photo of the answer; solid black tells you there is
   a shape here and refuses to tell you whose it is. */
.dex-one.off .dex-face{border-color:var(--line-soft);background:var(--panel-2)}
.dex-one.off .dex-face img{filter:brightness(0);opacity:.46}
.dex-one b{display:block;margin-top:5px;font:800 9.5px/1.2 system-ui,sans-serif;
  letter-spacing:.02em;color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dex-one.off b{color:var(--dimmer)}
.dex-one i{display:block;font:700 8.5px/1.3 system-ui,sans-serif;font-style:normal;
  color:var(--dimmer)}
.dex-one.off i{opacity:.7}
.dex-note{margin-top:14px;text-align:center;font:600 12px/1.5 system-ui,sans-serif;
  color:var(--dimmer)}

/* ---- one card, opened ---- */
.rwd-back{margin-bottom:10px}
.sheet-rows .rwd-back{min-height:42px;font-size:11.5px;color:var(--dim)}
.rwd-open{text-align:center}
/* The card and the character it holds, on one stage. .shot keeps its own
   clipping -- the cutout stands outside it. */
.rwd-stage{position:relative;width:min(74%,250px);margin:0 auto}
.rwd-open .shot{width:100%;aspect-ratio:5/7;border-radius:12px;
  overflow:hidden;border:1px solid var(--line)}
.rwd-pull{
  position:absolute;z-index:2;top:-22px;right:-34px;
  width:104px;height:104px;object-fit:contain;pointer-events:none;
  filter:drop-shadow(0 5px 12px #000c);
}
.rwd-open.on .rwd-pull{filter:drop-shadow(0 5px 12px #000c) drop-shadow(0 0 16px #ffc13d47)}
/* NOT EARNED IS NOT A SPOILER. The card behind it is already dimmed to a
   shape; the character gets the same silhouette the Dex grid uses, so this
   screen never hands over what the Dex tab is asking you to go and find. */
.rwd-open.off .rwd-pull{filter:brightness(0);opacity:.42}
@media (max-width:359px){
  .rwd-pull{width:88px;height:88px;top:-18px;right:-14px}
}
.rwd-open .shot img{width:100%;height:100%;object-fit:cover;display:block}
.rwd-open.off .shot img{filter:grayscale(1) brightness(.3);opacity:.62}
.rwd-open h3{margin:12px 0 2px;font:800 17px/1.2 system-ui,sans-serif;color:var(--text)}
.rwd-open .task{margin:0;font:800 11px/1.4 system-ui,sans-serif;letter-spacing:.09em;
  color:var(--gold)}
.rwd-open.off .task{color:var(--dim)}
.rwd-open .who{margin:10px 0 0;font:600 12px/1.5 system-ui,sans-serif;color:var(--dim)}
.rwd-open .got{margin:12px 0 0;font:700 11.5px/1.4 system-ui,sans-serif;color:var(--green)}

@media (max-width:349px){
  .rwd-grid{gap:8px 5px}
  .rwd small{font-size:8px}
  .dex-grid{grid-template-columns:repeat(3,1fr)}
}

/* Desktop only has to not look silly. Three stretched columns at 1280px
   made each card 420px wide, which is a poster, not a grid. Cap the column
   and center the lot -- margin-inline, not the margin shorthand, because
   the shorthand above already set the inline margins to 0. */
@media (min-width:520px){
  .rwd-grid{grid-template-columns:repeat(auto-fill,minmax(104px,1fr))}
  .rwd-grid,.dex-grid,.rwd-secret,.rwd-bar,.rwd-tabs,.rwd-open,.dex-note{
    max-width:560px;margin-inline:auto}
  .dex-grid{grid-template-columns:repeat(8,1fr)}
}


/* ---- the prizes tab ---- */
.prize{
  text-align:center;padding:18px 14px 16px;border-radius:14px;
  border:1px solid var(--line);background:var(--panel-2);
}
.prize.is-won{border-color:var(--gold);background:#ffc13d12}
.prize-art{width:112px;aspect-ratio:5/7;margin:0 auto 14px;border-radius:9px;
  overflow:hidden;border:1px solid var(--line)}
.prize-art img{width:100%;height:100%;object-fit:cover;display:block}
.prize.is-waiting .prize-art img{filter:grayscale(1) brightness(.3);opacity:.62}
.prize.is-won .prize-art{border-color:#ffc13d66}
.prize b{display:block;font:800 18px/1.25 system-ui,sans-serif;color:var(--text)}
.prize.is-won b{color:var(--gold)}
.prize-state{display:block;margin-top:6px;font:800 11px/1.4 system-ui,sans-serif;
  letter-spacing:.07em;color:var(--dim)}
.prize.is-won .prize-state{color:var(--green)}
.prize .rwd-bar{margin:14px 2px 0}
.prize-how{display:block;margin-top:10px;font:600 12px/1.5 system-ui,sans-serif;
  color:var(--dimmer)}

/* ======================================================================
   THE MOMENT A CARD LANDS.
   ====================================================================== */

/* The count on COLLECTION. Same pill as the bell's, over its own icon --
   .navdot is tuned to sit on the corner of your face in the MENU slot, and
   COLLECTION's icon is centered, so it needs its own two numbers. */
.navdot--mine{bottom:38px;left:calc(50% + 12px)}
@media (max-width:340px){ .navdot--mine{left:calc(50% + 9px)} }

.won{position:fixed;inset:0;z-index:120;display:grid;place-items:center;padding:24px;touch-action:manipulation}
.won-dim{position:absolute;inset:0;background:#02040abf;backdrop-filter:blur(3px)}
.won-box{
  /* OVERFLOW WAS HIDDEN AND THE PULLKIN NEEDS OUT. The card stays inside
     .won-art, which does its own clipping to keep its corners; the only
     thing that crosses this edge is the character, which is the point. The
     rays are 330px against a 320px panel and are masked to nothing long
     before that, so letting them past costs nothing visible. */
  position:relative;overflow:visible;width:min(100%,320px);text-align:center;
  padding:22px 20px 20px;border-radius:18px;
  border:1px solid var(--gold);background:#0b1322;
  box-shadow:0 20px 60px #000c,0 0 40px #ffc13d22;
  opacity:0;transform:translateY(14px) scale(.96);
  transition:opacity .22s ease,transform .26s cubic-bezier(.2,.9,.3,1.1);
}
.won.is-in .won-box{opacity:1;transform:none}
/* On the way out the panel gets out of the way fast, because the card
   flying to COLLECTION is the thing worth watching. */
.won.is-going .won-dim{opacity:0;transition:opacity .28s ease}
.won.is-going .won-box{opacity:0;transform:scale(.97);transition:opacity .18s ease,transform .18s ease}
.won.is-going .won-art{opacity:0}

.won-kicker{
  /* 34 rather than 14: the Pullkin lands above the card's top corner and
     this is the headroom it lands in. Without it the leap finishes on top
     of the word INFINITE. */
  margin:0 0 34px;font:800 10.5px/1.35 system-ui,sans-serif;letter-spacing:.11em;
  color:var(--gold);
}
/* ---- THE CARD, MADE A FUSS OF ----------------------------------------
   Three layers behind one card: rays that turn, a halo that breathes, and
   a shine that crosses the face. Each one is quiet on its own; together
   they read as "this is rare" without a single frame of video. */
.won-stage{position:relative;width:158px;margin:0 auto 16px}

/* Rays. A conic gradient of thin gold wedges, spun slowly and blurred, then
   faded out at the edges with a mask so it reads as light rather than as a
   pinwheel with a hard rim. */
.won-rays{
  position:absolute;left:50%;top:50%;width:330px;height:330px;
  margin:-165px 0 0 -165px;pointer-events:none;
  background:conic-gradient(from 0deg,
    #ffc13d00 0deg, #ffc13d55 6deg, #ffc13d00 14deg,
    #ffc13d00 40deg, #ffd47244 46deg, #ffc13d00 54deg,
    #ffc13d00 90deg, #ffc13d55 96deg, #ffc13d00 104deg,
    #ffc13d00 140deg, #ffd47244 146deg, #ffc13d00 154deg,
    #ffc13d00 190deg, #ffc13d55 196deg, #ffc13d00 204deg,
    #ffc13d00 240deg, #ffd47244 246deg, #ffc13d00 254deg,
    #ffc13d00 290deg, #ffc13d55 296deg, #ffc13d00 304deg,
    #ffc13d00 340deg, #ffd47244 346deg, #ffc13d00 354deg);
  -webkit-mask:radial-gradient(circle,#000 22%,#0009 48%,transparent 70%);
          mask:radial-gradient(circle,#000 22%,#0009 48%,transparent 70%);
  filter:blur(1px);
  opacity:0;
  animation:wonSpin 14s linear infinite, wonRaysIn .9s ease .12s forwards;
}
@keyframes wonSpin{to{transform:rotate(360deg)}}
@keyframes wonRaysIn{to{opacity:.85}}

/* The halo. Just a soft gold disc that breathes, sitting under the card so
   the card looks lit rather than pasted on. */
.won-halo{
  position:absolute;left:50%;top:50%;width:250px;height:250px;
  margin:-125px 0 0 -125px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,#ffc13d4d 0%,#ffc13d1f 42%,transparent 68%);
  animation:wonBreathe 2.8s ease-in-out infinite;
}
@keyframes wonBreathe{
  0%,100%{transform:scale(.92);opacity:.75}
  50%    {transform:scale(1.06);opacity:1}
}

.won-art{
  position:relative;z-index:2;
  width:158px;aspect-ratio:5/7;border-radius:11px;overflow:hidden;
  border:1px solid #ffc13d99;
  box-shadow:0 10px 30px #000c,0 0 34px #ffc13d55,0 0 70px #ffc13d22;
  animation:wonPop .62s cubic-bezier(.2,1.5,.4,1) both;
}
@keyframes wonPop{
  from{transform:scale(.62) rotate(-7deg);opacity:0}
  60% {transform:scale(1.04) rotate(1.5deg);opacity:1}
  to  {transform:scale(1) rotate(0)}
}
.won-art img{width:100%;height:100%;object-fit:cover;display:block}

/* ---- THE PULLKIN, OUT OF THE FRAME ------------------------------------
   The card is the collectible and stays whole; this is the character
   standing clear of it, over the top-right corner, so the two read as two
   things rather than as one picture with a picture on it. It lands a beat
   after the card -- the card arrives, THEN the Pullkin jumps out -- which
   is the half second the whole moment is built around.

   It lives on .won-stage, not in .won-art: that one is overflow:hidden to
   keep the card's rounded corners, and anything inside it gets clipped at
   the edge it is supposed to be crossing. */
.won-pull{
  position:absolute;z-index:3;top:-30px;right:-50px;
  width:126px;height:126px;object-fit:contain;pointer-events:none;
  filter:drop-shadow(0 6px 14px #000d) drop-shadow(0 0 20px #ffc13d59);
  animation:wonLeap .58s cubic-bezier(.2,1.6,.35,1) .26s both,
            wonFloat 3.4s ease-in-out .9s infinite;
}
@keyframes wonLeap{
  from{transform:translate(-14px,26px) scale(.35) rotate(-16deg);opacity:0}
  62% {transform:translate(0,-6px) scale(1.09) rotate(3deg);opacity:1}
  to  {transform:translate(0,0) scale(1) rotate(0)}
}
/* Barely moving. Enough that it reads as alive rather than pasted on, not
   enough to pull the eye off the name underneath. */
@keyframes wonFloat{
  0%,100%{transform:translateY(0) rotate(0)}
  50%    {transform:translateY(-5px) rotate(-1.5deg)}
}
/* On the way out it goes with the panel -- the CARD is the thing that flies
   to COLLECTION, and two things flying in two directions is neither. */
.won.is-going .won-pull{opacity:0;transition:opacity .16s ease}

/* A narrow phone has less room beside the stage than the overhang wants. */
@media (max-width:359px){
  .won-pull{width:104px;height:104px;top:-24px;right:-16px}
}
@media (prefers-reduced-motion:reduce){
  .won-pull{animation:none}
}

/* The shine. One band of light crossing the face every few seconds -- the
   thing that makes a foil card look like a foil card. */
.won-art::after{
  content:'';position:absolute;inset:-40%;
  background:linear-gradient(103deg,
    #fff0 42%, #ffffff26 47%, #ffffff5e 50%, #ffffff26 53%, #fff0 58%);
  transform:translateX(-120%);
  animation:wonShine 3.1s ease-in-out 1s infinite;
  pointer-events:none;
}
@keyframes wonShine{
  0%      {transform:translateX(-120%)}
  55%,100%{transform:translateX(120%)}
}

/* 51/50 is not the same event, so it does not get the same amount of light.
   Whiter, faster, brighter -- and the panel itself picks up the glow. */
.won.is-secret .won-box{box-shadow:0 20px 60px #000c,0 0 70px #ffc13d4d}
.won.is-secret .won-rays{
  animation-duration:9s,.9s;
  background:conic-gradient(from 0deg,
    #fff0 0deg, #fff9 5deg, #fff0 12deg,
    #fff0 30deg, #ffd472aa 35deg, #fff0 42deg,
    #fff0 60deg, #fff9 65deg, #fff0 72deg,
    #fff0 90deg, #ffd472aa 95deg, #fff0 102deg,
    #fff0 120deg, #fff9 125deg, #fff0 132deg,
    #fff0 150deg, #ffd472aa 155deg, #fff0 162deg,
    #fff0 180deg, #fff9 185deg, #fff0 192deg,
    #fff0 210deg, #ffd472aa 215deg, #fff0 222deg,
    #fff0 240deg, #fff9 245deg, #fff0 252deg,
    #fff0 270deg, #ffd472aa 275deg, #fff0 282deg,
    #fff0 300deg, #fff9 305deg, #fff0 312deg,
    #fff0 330deg, #ffd472aa 335deg, #fff0 342deg);
}
.won.is-secret .won-halo{
  background:radial-gradient(circle,#fff6 0%,#ffc13d3d 40%,transparent 68%);
  animation-duration:1.9s;
}
.won.is-secret .won-art{border-color:#fff;box-shadow:0 10px 30px #000c,0 0 46px #ffe9a8aa,0 0 90px #ffc13d44}
.won-box b{display:block;font:800 19px/1.2 system-ui,sans-serif;color:var(--text)}
.won-box small{
  display:block;margin-top:5px;font:800 10.5px/1.4 system-ui,sans-serif;
  letter-spacing:.08em;color:var(--dim);
}
.won-more{margin:12px 0 0;font:700 12px/1.4 system-ui,sans-serif;color:var(--gold-soft)}
.won-prize{margin:12px 0 0;font:800 13px/1.4 system-ui,sans-serif;color:var(--green)}
/* THE TAP HAS TO LOOK LIKE IT LANDED. Six hundred milliseconds of flight
   with no acknowledgement at the point of contact is how you get a second
   tap. */
.won-ok:active{transform:translateY(1px);filter:brightness(.93)}
.won-ok{
  display:block;width:100%;margin-top:18px;min-height:46px;border-radius:12px;
  border:1px solid var(--gold);background:var(--gold);color:#04070f;
  font:800 12px/1 system-ui,sans-serif;letter-spacing:.09em;
}
.won-ok:active{transform:translateY(1px)}

/* The clone that makes the trip. Keeps the frame so it reads as the card,
   not as a rectangle. */
.won-ghost{
  border-radius:11px;overflow:hidden;border:1px solid #ffc13d99;
  box-shadow:0 10px 30px #000a,0 0 30px #ffc13d55;
  animation:none;
}
.won-ghost::after{display:none}
.won-ghost img{width:100%;height:100%;object-fit:cover;display:block}

@media (prefers-reduced-motion:reduce){
  .won-box{transition:none;opacity:1;transform:none}
  .won-rays,.won-halo,.won-art,.won-art::after{animation:none}
  .won-rays{opacity:.6}
}

/* ======================================================================
   AN EARNED CARD, IN THE FEED.

   The gold is the whole point: scrolling past a wall of blue-framed posts,
   this one has to stop a thumb. It is the only post in the feed that is
   not a photograph of a real card, and it should not pretend to be one.
   ====================================================================== */
.post.is-reward{
  border:1px solid var(--gold);
  border-radius:16px;
  background:linear-gradient(180deg,#ffc13d0f,#ffc13d00 42%);
  box-shadow:0 0 0 1px #ffc13d1f,0 10px 34px #0007,0 0 30px #ffc13d1a;
  overflow:hidden;
}
/* Finishing the set is not the same event as earning card twelve. */
.post.is-reward.is-secret{
  border-color:#ffe9a8;
  background:linear-gradient(180deg,#ffe9a81a,#ffc13d00 46%);
  box-shadow:0 0 0 1px #ffe9a833,0 10px 34px #0008,0 0 46px #ffc13d33;
}

/* The line that says what happened, above the art rather than below it --
   somebody scrolling reads the banner, not the caption. */
/* TWO LINES: WHAT HAPPENED, AND WHAT THEY DID.
   The label is the quiet one -- everybody works out what INFINITE REWARD
   EARNED means after seeing it twice. The line under it is the one carrying
   the information: it is the task that paid the card, and it is the only
   place on the feed that ever tells a stranger how to get one. So it is
   bigger and brighter than the label above it, which is the reverse of
   where this started. */
.reward-flag{
  margin:0;padding:9px 14px 10px;
  font:800 9.5px/1.2 system-ui,sans-serif;letter-spacing:.13em;
  color:var(--dim);text-align:center;
  border-top:1px solid #ffc13d2e;border-bottom:1px solid #ffc13d2e;
  background:#ffc13d0f;
}
.reward-flag b{
  display:block;margin-top:4px;
  font:800 12px/1.3 system-ui,sans-serif;letter-spacing:.07em;color:var(--gold);
}
.post.is-reward.is-secret .reward-flag{background:#ffc13d1c}
.post.is-reward.is-secret .reward-flag b{color:#ffe9a8;letter-spacing:.1em;font-size:12.5px}

.post.is-reward .frame{position:relative;background:#04070f}
.post.is-reward .rail figure{border-radius:10px;overflow:hidden}
.post.is-reward .rail img{border-radius:10px}

/* How many are in here, so a post you can swipe says so before you swipe. */
.reward-count{
  position:absolute;right:10px;top:10px;z-index:2;
  min-width:26px;height:22px;padding:0 7px;border-radius:999px;
  background:#04070fd9;border:1px solid #ffc13d66;color:var(--gold);
  font:800 11px/21px system-ui,sans-serif;text-align:center;
  backdrop-filter:blur(4px);pointer-events:none;
}

.post.is-reward .caption.reward-cap i{font-style:normal;color:var(--dim);letter-spacing:.05em;
  font-weight:800;font-size:11px}

/* ---- RIBBONS, beside a name -------------------------------------------
   Same size and rhythm as the founding badge so a row with three marks
   still reads as a name with marks after it, not as a row of icons. */
/* flex:none, like .vb -- .nameline is a flex row, and without it a ribbon
   is a shrinkable item that gets squeezed to nothing beside a long name. */
.rb{flex:none;display:inline-block;width:15px;height:15px;vertical-align:-2px;margin-left:4px}
.caption .rb,.cwho .rb{margin-left:3px}
.rb svg{width:100%;height:100%;display:block}
.rb svg circle{fill:currentColor;opacity:.92}
.rb svg path{fill:none;stroke:currentColor;stroke-width:2.6;
  stroke-linejoin:round;stroke-linecap:round;opacity:.92}
.rb--half {color:#c98b4b}
.rb--whole{color:#ffc13d;filter:drop-shadow(0 0 4px #ffc13d66)}

/* ---- THE ROW THAT HAS THE NEWS ----------------------------------------
   The count on the COLLECTION button says there is something; this says
   WHICH thing. Same gold pill as the notifications tile, on the row that
   opens the sheet the count came from. */
.sheet-rows .go.has-news{position:relative;border-color:var(--gold);color:var(--gold)}
.sheet-rows .go.has-news svg{stroke:var(--gold)}
.row-n{
  margin-left:auto;flex:none;
  min-width:22px;height:22px;padding:0 6px;border-radius:999px;
  background:var(--gold);color:#04070f;
  font:800 11px/22px system-ui,sans-serif;font-style:normal;letter-spacing:0;
  text-align:center;
}
/* One wiggle, on open. Long enough to catch an eye, over before anybody
   starts reading -- a row that keeps moving is a row you cannot read. */
.sheet-rows .go.has-news{animation:rowNudge .62s ease .18s 1}
@keyframes rowNudge{
  0%,100%{transform:translateX(0)}
  18%{transform:translateX(-4px)}
  38%{transform:translateX(4px)}
  58%{transform:translateX(-3px)}
  78%{transform:translateX(2px)}
}

/* What the number meant, at the top of the cards tab. */
.rwd-news{
  margin:0 0 12px;padding:9px 12px;border-radius:10px;
  background:#ffc13d14;border:1px solid #ffc13d3d;
  font:700 12px/1.4 system-ui,sans-serif;color:var(--gold-soft);text-align:center;
}

@media (prefers-reduced-motion:reduce){
  .sheet-rows .go.has-news{animation:none}
}


/* ======================================================================
   THE FIRST MINUTE
   Shown once, on somebody's first visit after signing up. Sits on the same
   kind of panel as the celebration so the two read as one family -- this is
   the screen that tells you cards exist, and the next one you see is a card
   landing.
   ====================================================================== */
.hey{position:fixed;inset:0;z-index:130;display:grid;place-items:center;padding:20px;touch-action:manipulation}
.hey-dim{position:absolute;inset:0;background:#02040ad9;backdrop-filter:blur(3px)}
.hey-box{
  position:relative;width:min(100%,330px);max-height:92dvh;overflow-y:auto;
  text-align:center;padding:26px 20px 18px;border-radius:20px;
  border:1px solid var(--gold);background:#0b1322;
  box-shadow:0 22px 64px #000d,0 0 46px #ffc13d1f;
  opacity:0;transform:translateY(16px) scale(.97);
  transition:opacity .24s ease,transform .3s cubic-bezier(.2,.9,.3,1.1);
}
.hey.is-in .hey-box{opacity:1;transform:none}

/* Glimbit does the greeting. Dex #001, and the only character on the app
   that reads as a mascot rather than as one of twenty-five. */
.hey-pull{
  display:block;width:104px;height:104px;object-fit:contain;margin:0 auto 4px;
  filter:drop-shadow(0 6px 14px #000c) drop-shadow(0 0 22px #ffc13d4d);
  animation:heyBob 3.6s ease-in-out .4s infinite;
}
@keyframes heyBob{
  0%,100%{transform:translateY(0) rotate(0)}
  50%    {transform:translateY(-6px) rotate(-2deg)}
}
.hey-kicker{margin:0 0 6px;font:800 10px/1.3 system-ui,sans-serif;
  letter-spacing:.13em;color:var(--gold)}
.hey-h{margin:0 0 4px;font:800 21px/1.2 system-ui,sans-serif;color:var(--text)}
.hey-sub{margin:0 0 18px;font:600 12.5px/1.5 system-ui,sans-serif;color:var(--dim)}

/* ROWS, NOT A PARAGRAPH. Three things to do is a list; three things to do
   written as prose is something nobody finishes reading. */
.hey-list{list-style:none;margin:0 0 16px;padding:0;display:grid;gap:8px;text-align:left}
.hey-list li{
  display:flex;align-items:center;gap:12px;padding:11px 13px;
  border-radius:12px;border:1px solid var(--line);background:var(--panel-2);
}
.hey-ico{flex:none;display:grid;place-items:center;width:22px;height:22px}
.hey-ico svg{width:19px;height:19px;stroke:var(--gold);fill:none;stroke-width:2}
.hey-txt{min-width:0}
.hey-txt b{display:block;font:800 11.5px/1.2 system-ui,sans-serif;
  letter-spacing:.07em;color:var(--text)}
/* The card it pays. Gold, because it is the reward half of the sentence. */
.hey-txt i{display:block;margin-top:3px;font:700 10.5px/1.3 system-ui,sans-serif;
  font-style:normal;letter-spacing:.02em;color:var(--gold)}

.hey-prize{margin:0 0 16px;font:600 12px/1.5 system-ui,sans-serif;color:var(--dim)}
.hey-prize b{color:var(--gold);font-weight:800}

.hey-go,.hey-ok{
  display:block;width:100%;min-height:48px;border-radius:12px;
  font:800 12px/1 system-ui,sans-serif;letter-spacing:.08em;
}
.hey-go{background:var(--gold);color:#0b1322;border:0}
.hey-go:active{transform:translateY(1px)}
/* THE WAY OUT IS ALWAYS VISIBLE. Every screen needs one, and on a panel
   that covers the app it is the only one there is. */
.hey-ok{margin-top:8px;background:transparent;color:var(--dim);
  border:1px solid var(--line)}

/* THE WAY OUT MUST NOT NEED A SCROLL. At 320x568 the panel ran past the
   bottom of the screen and START LOOKING -- the only way out of a thing that
   covers the whole app -- sat below the fold. It is reachable, because the
   panel scrolls, but a way out you have to go looking for is most of the way
   to not having one. Everything shrinks instead. */
@media (max-width:359px){
  .hey-box{padding:18px 16px 14px}
  .hey-pull{width:74px;height:74px}
  .hey-h{font-size:18px}
  .hey-sub{margin-bottom:12px;font-size:12px}
  .hey-list{gap:6px;margin-bottom:12px}
  .hey-list li{padding:9px 10px;gap:10px}
  .hey-prize{margin-bottom:12px}
  .hey-go,.hey-ok{min-height:44px}
}
/* A SHORT SCREEN IS NOT ALWAYS A NARROW ONE -- a phone held in landscape,
   or a small window on a laptop. The mascot is the first thing to give up
   its space, because it is the one part carrying no information. */
@media (max-height:640px){
  .hey-pull{width:62px;height:62px;margin-bottom:0}
  .hey-box{padding-top:16px}
  .hey-sub{margin-bottom:12px}
  .hey-list{margin-bottom:12px}
  .hey-prize{margin-bottom:12px}
}
@media (prefers-reduced-motion:reduce){
  .hey-pull{animation:none}
  .hey-box{transition:none}
}

/* ======================================================================
   THE PROFILE CARD
   Top of a narrowed person feed -- which is what infinitepulls.com/<name>
   is. It went out first as a stack of labeled blocks, 369px of it, with the
   grail card as a thumbnail in a narrow column and a dead L-shaped gap
   beside the bio. That is a form, not a profile.

   THE GRAIL IS THE HEADER NOW. Its artwork is the band behind the name --
   blurred hard, dimmed, no longer legible as a picture -- and the card
   itself lies tilted over the bottom edge of it. Every profile on the site
   is lit by its owner's own card, using data that was already there, and
   the card came in under 200px.
   ====================================================================== */
.prof{
  position:relative;overflow:hidden;
  margin:0 12px 14px;border:1px solid var(--line);border-radius:14px;
  background:var(--panel);
}
.prof[hidden]{display:none}

/* ---- the band ----
   Not overflow:hidden: the grail card has to hang over its bottom edge, and
   the thing that needs clipping is the artwork, which has a box of its own
   to be clipped inside. */
.prof-band{position:relative;padding:14px 13px 13px}
.prof-art{
  position:absolute;inset:0;overflow:hidden;border-radius:13px 13px 0 0;
  pointer-events:none;
}
/* Inset well past the edges so the blur has real pixels to pull from --
   blurring to the boundary of a box leaves a pale rim all the way round. */
.prof-art::before{
  content:'';position:absolute;inset:-35% -12%;
  background-image:var(--art);background-size:cover;background-position:50% 30%;
  filter:blur(22px) saturate(1.35);opacity:.6;
}
/* THE DARKNESS FLOOR. A pale card -- a white-bordered vintage holo is the
   obvious one -- would otherwise wash the username out at exactly the size
   it is hardest to read. This never lets the band get lighter than this,
   whatever is behind it. */
.prof-art::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,#04070f8f 0%,#0b1322d4 56%,var(--panel) 100%);
}

/* CENTRED, NOT TOP-ALIGNED. The avatar is 54px and a name with no tagline
   under it is 22, so flex-start left thirty pixels of nothing beside every
   account that has not written one -- which is most of them. */
.prof-top{position:relative;z-index:2;display:flex;align-items:center;gap:11px}
.prof-face{
  flex:none;width:54px;height:54px;border-radius:50%;object-fit:cover;
  background:var(--panel-2);border:1px solid var(--gold);
  box-shadow:0 4px 14px #000a;
}
/* Room for the card in the corner, so a long name never runs under it. */
.prof-name{min-width:0;flex:1;padding-right:76px}
/* No card in the corner, no gutter for it. */
.prof:not(.has-art) .prof-name{padding-right:0}
.prof-name h2{
  margin:0;font:800 18px/1.2 system-ui,sans-serif;color:var(--gold);
  overflow-wrap:anywhere;text-shadow:0 2px 8px #000b;
}
.prof-tag{margin:3px 0 0;font:600 12.5px/1.45 system-ui,sans-serif;
  color:#c9d9ef;text-shadow:0 1px 6px #000b}

/* ---- the grail, lying on the profile ----
   The tilt and the overhang are the whole trick: square and tucked inside,
   it is a picture in a box; at an angle with its corner past the edge, it
   is a card somebody put down. */
.gtag{position:absolute;z-index:3;right:80px;bottom:9px;text-align:right;max-width:44%}
.gtag span{display:block;font:800 8px/1 system-ui,sans-serif;
  letter-spacing:.16em;color:var(--gold);text-shadow:0 1px 4px #000b}
.gtag b{display:block;margin-top:3px;font:800 10.5px/1.25 system-ui,sans-serif;
  color:var(--text);text-shadow:0 1px 6px #000b;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gcard{
  position:absolute;z-index:3;right:12px;bottom:-14px;width:62px;
  aspect-ratio:245/337;object-fit:cover;display:block;
  transform:rotate(7deg);border-radius:6px;
  border:1px solid #ffc13d8c;background:#04070f;
  box-shadow:0 8px 22px #000d,0 0 18px #ffc13d3d;
}

/* The overhanging corner lands in this padding rather than on the bio --
   and when there is no grail there is no corner, so the gap closes. An
   account with nothing filled in yet is the common case and it should not
   look like a card with its middle missing. */
.prof-rest{padding:20px 13px 12px}
.prof:not(.has-art) .prof-rest{padding-top:12px}
.prof:not(.has-art) .prof-band{padding-bottom:11px}

.prof-bio{min-width:0}
/* TWO LINES, THEN ASK. A bio is the one thing here somebody can make
   arbitrarily long, and an unbounded one pushes the badges and the numbers
   -- the parts that are the same on every profile -- off the screen. */
.pb-text{
  margin:0;font:500 12.5px/1.5 system-ui,sans-serif;color:var(--text);
  overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;
  -webkit-line-clamp:2;overflow-wrap:anywhere;
}
.prof-bio.is-open .pb-text{-webkit-line-clamp:unset;display:block}
.pb-more{
  margin-top:5px;padding:3px 0;
  font:800 9.5px/1 system-ui,sans-serif;letter-spacing:.12em;color:var(--blue);
  -webkit-tap-highlight-color:transparent;
}
.pb-more[hidden]{display:none}
.pb-more:active{color:var(--blue-soft)}

/* ---- badges earned ----
   Goals that reached 100%. Wraps rather than scrolls: there are eight in
   the whole game, so the row can never get long enough to need a swipe. */
.prof-badges{
  display:flex;flex-wrap:wrap;gap:9px;margin-top:12px;
  padding-top:11px;border-top:1px solid var(--line-soft);
}
.pbadge{width:60px;text-align:center}
.pbadge img{width:40px;height:40px;object-fit:contain;display:block;margin:0 auto}
.pbadge.is-plain b{
  display:grid;place-items:center;width:40px;height:40px;margin:0 auto;
  border-radius:11px;background:var(--panel-2);border:1px solid var(--line);
  font-size:18px;
}
.pbadge i{
  display:block;margin-top:4px;font:700 8.5px/1.25 system-ui,sans-serif;
  font-style:normal;color:var(--dimmer);
}

/* ---- the three numbers ----
   ONE STRIP, NOT THREE BOXES. Three bordered tiles is a lot of furniture
   around 27, 4 and 18/50; hairlines say the same thing in a third of the
   height and read left to right in one go.

   Doors on your own profile, plain numbers on anybody else's: there is no
   public page for another person's wish list or rewards -- reward_sweep
   runs on auth.uid() -- so a link would be a promise this app cannot keep.
   The number is the part a visitor wanted anyway. */
.prof-tiles{
  display:flex;margin-top:12px;padding-top:11px;
  border-top:1px solid var(--line-soft);
}
.ptile{
  flex:1;min-width:0;display:flex;align-items:baseline;justify-content:center;gap:5px;
  padding:4px 2px;text-decoration:none;
  -webkit-tap-highlight-color:transparent;
}
.ptile + .ptile{border-left:1px solid var(--line-soft)}
.ptile b{font:800 14.5px/1 system-ui,sans-serif;color:var(--text)}
.ptile i{font:800 8px/1 system-ui,sans-serif;letter-spacing:.11em;
  font-style:normal;color:var(--dimmer)}
.ptile.is-door b{color:var(--blue)}
.ptile.is-door:active b{color:var(--blue-soft)}

@media (max-width:359px){
  .prof-face{width:48px;height:48px}
  .prof-name{padding-right:66px}
  .prof-name h2{font-size:16.5px}
  .gcard{width:54px;right:10px}
  .gtag{right:70px}
  .pbadge{width:54px}
  .pbadge img,.pbadge.is-plain b{width:36px;height:36px}
}

/* ---- SCAN TO FOLLOW (25 Sep 2026, SOCIAL-NEXT part 4) ----
   The little QR mark beside a name, and the full-screen code it opens.
   The code is always black on white, in both themes: scanners want contrast,
   not our palette. */
.prof-qr{
  display:inline-grid;place-items:center;vertical-align:middle;
  width:28px;height:28px;margin-left:8px;padding:0;border-radius:8px;
  border:1px solid var(--line);background:var(--panel);color:var(--blue-soft);
  cursor:pointer;text-shadow:none;
}
.prof-qr:active{transform:scale(.94)}
.qr-sheet{
  position:fixed;inset:0;z-index:9000;display:grid;place-items:center;
  padding:20px 16px calc(20px + env(safe-area-inset-bottom));
  background:#04070fe6;backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
}
.qr-card{
  width:min(100%,380px);background:#fff;color:#04070f;border-radius:22px;
  padding:20px 20px 16px;text-align:center;box-shadow:0 20px 60px #000c;
}
.qr-who{display:flex;align-items:center;justify-content:center;gap:10px;margin-bottom:12px}
.qr-who img{width:40px;height:40px;border-radius:50%;object-fit:cover;border:2px solid #ffc13d}
.qr-who b{font:800 20px/1.2 system-ui,sans-serif;overflow-wrap:anywhere}
.qr-code{position:relative;aspect-ratio:1;display:grid;place-items:center}
.qr-code canvas{width:100%;height:auto;image-rendering:pixelated;display:block}
.qr-wait{position:absolute;inset:0;display:grid;place-items:center;
  font:600 14px/1.4 system-ui,sans-serif;color:#55677e;padding:0 20px}
.qr-say{margin:10px 0 2px;font:800 16px/1.3 system-ui,sans-serif}
.qr-url{margin:0 0 14px;font:600 13px/1.3 system-ui,sans-serif;color:#55677e;overflow-wrap:anywhere}
.qr-acts{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.qr-acts button{
  min-height:44px;border-radius:12px;border:0;cursor:pointer;
  font:800 13px/1 system-ui,sans-serif;letter-spacing:.06em;
  background:#04070f;color:#fff;
}
.qr-acts button + button{background:#ffc13d;color:#04070f}

/* ======================================================================
   THE PROFILE, INSTAGRAM-STYLE (25 Sep 2026, SOCIAL-NEXT part 5)
   Photo in a gold ring, four numbers beside it, then name/bio/value/socials,
   then FOLLOW · SHARE PROFILE · the little QR, then the badges.
   ====================================================================== */
.prof.ph{padding:14px 13px 13px}
.ph-top{display:flex;align-items:center;gap:14px}
.ph-ring{flex:none;width:84px;height:84px;border-radius:50%;padding:3px;background:var(--gold)}
.ph-ring.is-live{background:conic-gradient(#ff2d55,#ff7a00,#ff2d55)}
.ph-face{width:100%;height:100%;border-radius:50%;object-fit:cover;display:block;
  border:3px solid var(--panel);background:var(--panel-2)}
.ph-right{flex:1;min-width:0}
.ph-name{margin:0 0 7px;font:800 16px/1.2 system-ui,sans-serif;color:var(--text);overflow-wrap:anywhere}
.ph-stats{display:flex;justify-content:space-between;gap:4px}
.ps{display:flex;flex-direction:column;align-items:flex-start;min-width:0;padding:0;border:0;background:none;
  color:inherit;text-align:left;-webkit-tap-highlight-color:transparent}
.ps b{font:800 16px/1.15 system-ui,sans-serif;color:var(--text);white-space:nowrap}
.ps i{font:600 11.5px/1.3 system-ui,sans-serif;font-style:normal;color:var(--dim)}
button.ps b{color:var(--blue-soft)}
.inf{color:var(--gold);margin-right:1px}
.ph-tag{margin:10px 0 0;font:600 12.5px/1.4 system-ui,sans-serif;color:var(--dim)}
.prof.ph .prof-bio{margin-top:9px}
.ph-chips{display:flex;gap:8px;margin-top:10px}
.ph-val{font:700 12px/1 system-ui,sans-serif;color:var(--green);padding:6px 10px;
  border:1px solid var(--line);border-radius:999px}
.ph-soc{display:flex;gap:10px;margin-top:10px}
.psoc{width:34px;height:34px;border-radius:50%;border:1px solid var(--line);display:grid;place-items:center;
  color:var(--blue-soft);text-decoration:none}
.psoc:active{transform:scale(.94)}
.ph-btns{display:grid;grid-template-columns:1fr 1fr 40px;gap:8px;margin-top:12px}
.pbtn{height:38px;border-radius:10px;border:1px solid var(--line);background:var(--panel-2);color:var(--text);
  font:800 12.5px/1 system-ui,sans-serif;letter-spacing:.06em;cursor:pointer;
  display:grid;place-items:center;text-decoration:none;padding:0 6px}
.pbtn.follow{background:var(--gold);color:#04070f;border:0}
.pbtn.follow.on{background:var(--panel-2);color:var(--text);border:1px solid var(--line)}
.pbtn:active,.pqr:active{transform:scale(.97)}
.pqr{height:38px;width:40px;border-radius:10px;border:0;background:#fff;padding:3px;display:grid;place-items:center;cursor:pointer}
.pqr canvas{width:32px;height:32px;image-rendering:pixelated;display:block}
.ph-badges{display:flex;gap:12px;margin-top:14px;overflow-x:auto;scrollbar-width:none;padding-bottom:2px}
.ph-badges::-webkit-scrollbar{display:none}
.ph-badges .pbadge{flex:none}
.ph-badges .pbadge img,.ph-badges .pbadge.is-plain b{width:54px;height:54px;border-radius:50%;
  border:2px solid var(--line);background:var(--panel-2);object-fit:contain}
@media (max-width:359px){
  .ph-ring{width:70px;height:70px}
  .ps b{font-size:14.5px}
  .ps i{font-size:10.5px}
}

/* ---- EVERYONE / FOLLOWING ---- */
.feedtabs{display:grid;grid-template-columns:1fr 1fr;margin:0 12px 10px;border-bottom:1px solid var(--line)}
.feedtabs[hidden]{display:none}
.feedtabs button{padding:11px 0 10px;border:0;background:none;color:var(--dim);
  font:800 12px/1 system-ui,sans-serif;letter-spacing:.1em;cursor:pointer}
.feedtabs button.on{color:var(--text);box-shadow:inset 0 -2px 0 var(--gold)}

/* ---- EDIT PROFILE sheet ---- */
.ep-sheet{position:fixed;inset:0;z-index:9000;display:flex;align-items:flex-end;justify-content:center;
  background:#04070fcc;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
.ep-panel{width:min(100%,480px);max-height:92vh;overflow-y:auto;background:var(--panel);
  border:1px solid var(--line);border-bottom:0;border-radius:18px 18px 0 0;
  padding:18px 16px calc(18px + env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:12px}
.ep-panel h3{margin:0;font:800 17px/1.2 system-ui,sans-serif;color:var(--text);text-align:center}
.ep-photo{display:flex;flex-direction:column;align-items:center;gap:8px}
.ep-photo img{width:84px;height:84px;border-radius:50%;object-fit:cover;border:3px solid var(--gold)}
.ep-change{font:800 12px/1 system-ui,sans-serif;letter-spacing:.08em;color:var(--blue-soft);cursor:pointer;padding:6px}
.ep-panel label{display:flex;flex-direction:column;gap:5px;font:700 12px/1 system-ui,sans-serif;color:var(--dim)}
.ep-panel label small{font-weight:600;color:var(--dimmer)}
.ep-panel input,.ep-panel textarea{font:500 16px/1.35 system-ui,sans-serif;color:var(--text);
  background:var(--ink);border:1px solid var(--line);border-radius:10px;padding:10px 12px;resize:vertical}
.ep-panel input:focus,.ep-panel textarea:focus{outline:none;border-color:var(--blue)}
.ep-link{font:700 13px/1.2 system-ui,sans-serif;color:var(--blue-soft);text-decoration:none}
.ep-status{margin:0;min-height:1em;font:600 13px/1.35 system-ui,sans-serif;color:var(--gold)}
.ep-save{height:46px;border-radius:12px;border:0;background:var(--gold);color:#04070f;
  font:800 14px/1 system-ui,sans-serif;letter-spacing:.08em;cursor:pointer}
.ep-save:disabled{opacity:.6}

.ep-note{margin:-4px 0 0;font:500 11.5px/1.4 system-ui,sans-serif;color:var(--dimmer)}
.ep-badge{display:flex;align-items:center;gap:10px;padding:10px;border:1px solid var(--line);border-radius:12px;background:var(--ink)}
.ep-badge img{flex:none;width:44px;height:44px}
.ep-badge div{flex:1;min-width:0}
.ep-badge b{display:block;font:800 13px/1.2 system-ui,sans-serif;color:var(--gold)}
.ep-badge small{display:block;margin-top:3px;font:500 11.5px/1.35 system-ui,sans-serif;color:var(--dim)}
.ep-badge button{flex:none;height:34px;padding:0 12px;border-radius:9px;border:0;background:var(--gold);color:#04070f;
  font:800 12px/1 system-ui,sans-serif;letter-spacing:.06em;cursor:pointer}
.ep-panel>*{flex:none}

/* ---- the chip's words are one run, so no gap before an apostrophe ---- */
.chip-t{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ======================================================================
   PROFILE TABS + GRIDS (25 Sep 2026)
   ====================================================================== */
.feed.is-grid > :not(#profcard):not(#ppane){display:none}
.ppane{margin:0 0 14px}
.ptabs{position:sticky;top:var(--stick,60px);z-index:30;display:grid;grid-template-columns:repeat(4,1fr);
  background:var(--ink);border-bottom:1px solid var(--line)}
.ptabs button{padding:11px 0 10px;border:0;background:none;color:var(--dim);display:grid;place-items:center;cursor:pointer}
.ptabs button.on{color:var(--text);box-shadow:inset 0 -2px 0 var(--gold)}
.inf-tab{font:800 24px/22px system-ui,sans-serif;color:inherit}
.ptabs button.on .inf-tab{color:var(--gold)}
.ptab-l{font:700 13.5px/22px system-ui,sans-serif;letter-spacing:0;color:inherit;white-space:nowrap}
.ptab-l .inf-mark{font-style:normal;font-weight:900;color:var(--gold)}
.ptab-l{display:block}
.ptabs button{padding-left:2px;padding-right:2px}
.ptabs .ptab-l{font-size:clamp(11.5px,3.4vw,14px);letter-spacing:-.01em}
.ptab-my{display:block;font:800 9.5px/1 system-ui,sans-serif;letter-spacing:.12em;color:var(--dim);margin-bottom:1px}
.ptabs button.on .ptab-my{color:var(--gold)}
.ptabs button.on .ptab-l{color:var(--text)}
.pgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:2px;margin-top:2px}
.pg-tile{position:relative;display:block;aspect-ratio:5/7;background:var(--panel-2);overflow:hidden;
  border:0;padding:0;cursor:pointer}
.pg-tile img{width:100%;height:100%;object-fit:cover;display:block}
.pg-tile.rw i{position:absolute;left:5px;bottom:4px;font:800 10px/1 system-ui,sans-serif;font-style:normal;
  color:#fff;text-shadow:0 1px 4px #000}
.pg-tile.dim img{filter:grayscale(1) brightness(.45)}
.pg-tile.dim{opacity:.7}
.pg-q{display:grid;place-items:center;width:100%;height:100%;font:800 28px/1 system-ui,sans-serif;color:var(--dimmer)}
.pg-count{grid-column:1/-1;padding:10px 12px 8px;font:800 13px/1 system-ui,sans-serif;color:var(--text)}
.pg-empty,.pg-wait{grid-column:1/-1;padding:28px 16px;text-align:center;font:600 13px/1.5 system-ui,sans-serif;color:var(--dim)}
.pg-tail{grid-column:1/-1;height:1px}

/* ---- the dollar figure on a card tile, and EARNED on a reward tile ---- */
.pg-val{position:absolute;left:5px;bottom:5px;padding:3px 6px;border-radius:6px;background:#04070fd9;
  font:800 11px/1 system-ui,sans-serif;color:var(--green)}
.pg-earned{position:absolute;top:5px;left:5px;padding:3px 5px;border-radius:5px;background:var(--gold);
  font:900 8.5px/1 system-ui,sans-serif;letter-spacing:.08em;font-style:normal;color:#04070f}
.pg-tile.rw.got{box-shadow:inset 0 0 0 2px var(--gold)}
/* ---- one reward card, opened ---- */
.rw-card{width:min(100%,340px);background:var(--panel);border:1px solid var(--line);border-radius:20px;
  padding:18px 18px 16px;text-align:center;color:var(--text)}
.rw-big{width:62%;aspect-ratio:5/7;object-fit:cover;border-radius:10px;display:block;margin:0 auto 10px}
.rw-big.dim{filter:grayscale(1) brightness(.5)}
.rw-big.q{display:grid;place-items:center;background:var(--panel-2);font:800 48px/1 system-ui,sans-serif;color:var(--dimmer)}
.rw-num{margin:0;font:800 12px/1 system-ui,sans-serif;color:var(--dim)}
.rw-card h3{margin:6px 0 10px;font:800 18px/1.2 system-ui,sans-serif}
.rw-how{margin:0;font:500 13.5px/1.45 system-ui,sans-serif;color:var(--text)}
.rw-how b{display:block;margin-bottom:3px;font:800 10px/1 system-ui,sans-serif;letter-spacing:.12em;color:var(--dim);text-transform:uppercase}
.rw-when{margin:12px 0 0;font:700 12.5px/1.3 system-ui,sans-serif;color:var(--dim)}
.rw-when.got{color:var(--gold)}

/* ---- earned rewards: the card, and under it what they did ---- */
.pg-rw{display:flex;flex-direction:column;gap:5px;padding:0 0 8px;border:0;background:none;cursor:pointer;text-align:left;min-width:0}
.pg-rw .pg-tile{width:100%}
.pg-did{padding:0 5px;font:600 10.5px/1.3 system-ui,sans-serif;color:var(--dim);
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}

/* ---- one post opened over the profile ---- */
.post-sheet{position:fixed;inset:0;z-index:55;overflow-y:auto;-webkit-overflow-scrolling:touch;
  background:#04070ff2;padding:calc(12px + env(safe-area-inset-top)) 0 calc(24px + env(safe-area-inset-bottom))}
.post-sheet-in{max-width:520px;margin:0 auto;background:var(--ink);border-radius:14px;overflow:hidden}

/* ---- CLAIM NOW (25 Sep 2026) ---- */
.claim-row{display:flex;flex-direction:column;gap:8px;margin-top:12px}
.claim-pill{display:flex;align-items:center;gap:9px;width:100%;padding:9px 10px 9px 12px;border-radius:999px;
  border:1px solid var(--gold);background:linear-gradient(90deg,#ffc13d22,#ffc13d0a);color:var(--text);
  font:700 13px/1.2 system-ui,sans-serif;text-align:left;cursor:pointer;animation:claimGlow 2.4s ease-in-out infinite}
.claim-pill span:not(.cp-star){flex:1;min-width:0}
.claim-pill b{flex:none;padding:7px 11px;border-radius:999px;background:var(--gold);color:#04070f;
  font:900 11px/1 system-ui,sans-serif;letter-spacing:.08em}
.claim-pill .cp-star{font:800 20px/1 system-ui,sans-serif;color:var(--gold)}
.claim-pill img{flex:none}
.claim-pill:disabled{opacity:.6;animation:none}
@keyframes claimGlow{50%{box-shadow:0 0 0 4px #ffc13d22}}
@media (prefers-reduced-motion:reduce){.claim-pill{animation:none}}
/* something is waiting: a gold dot on your face in the menu */
[data-menu].has-claim{position:relative}
[data-menu].has-claim::after{content:'';position:absolute;top:2px;right:2px;width:10px;height:10px;border-radius:50%;
  background:var(--gold);border:2px solid var(--ink)}

/* ---- WHO YOU ARE, under the wordmark (25 Sep 2026) ------------------- */
.tcenter{display:grid;justify-items:center;gap:6px;min-width:0}
.topme{display:inline-flex;align-items:center;gap:6px;max-width:100%;min-width:0;
  text-decoration:none;color:var(--dim, #8ba5c8);font:700 12px/1 system-ui,sans-serif}
.topme[hidden]{display:none}
.topme img,.topme .tl{width:18px;height:18px;border-radius:50%;flex:0 0 auto;object-fit:cover;
  border:1px solid var(--line)}
.topme .tl{display:grid;place-items:center;background:var(--gold);color:#04070f;font:800 10px/1 system-ui,sans-serif;border:0}
.topme b{font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text)}
.topme b::before{content:'@';color:var(--dim, #8ba5c8)}
.topme.out{color:var(--gold)}

/* ---- PHONE (25 Sep 2026): the texts yes-box in Edit profile, and the
   one-time "get a text when new cards drop" sheet ----------------------- */
.ep-panel label.ep-check{flex-direction:row;align-items:flex-start;gap:10px;font:600 12px/1.4 system-ui,sans-serif;color:var(--dim)}
.ep-panel label.ep-check input{flex:none;width:20px;height:20px;margin:1px 0 0;padding:0;accent-color:var(--gold)}
.ep-later{height:42px;border-radius:12px;border:1px solid var(--line);background:none;color:var(--dim);
  font:800 12px/1 system-ui,sans-serif;letter-spacing:.08em;cursor:pointer}

/* ---- YOUR VALUE in the edit box (26 Sep 2026) --------------------------- */
.ce-warn{margin:6px 0 0;font:600 11.5px/1.4 system-ui,sans-serif;color:#f0a24a}
.ce-warn:empty{display:none}
.ce-sold{color:var(--gold, #ffc928);font-weight:700;text-decoration:none;white-space:nowrap}

/* ======================================================================
   THE JOIN BOX (27 Sep 2026) -- guests only. See showJoin() in feed.js.
   ====================================================================== */
html.join-open{overflow:hidden}
.topme.out.join{padding:3px 12px;border-radius:999px;background:var(--gold);color:#04070f;
  font-weight:800;letter-spacing:.02em}
.joinbox{position:fixed;inset:0;z-index:200;display:grid;place-items:center;padding:16px;
  background:rgba(2,4,10,.72);animation:jb-in .18s ease-out}
.jb-card{width:100%;max-width:360px;max-height:calc(100vh - 32px);overflow:auto;background:#fff;color:#0d1725;
  border-radius:20px;padding:24px 20px 18px;box-shadow:0 20px 60px rgba(0,0,0,.45);text-align:center}
.jb-why{margin:0 0 8px;color:#8a5a06;font:700 13px/1.3 system-ui,sans-serif}
.jb-h{margin:0 0 14px;font:900 25px/1.15 system-ui,sans-serif;letter-spacing:-.01em;color:#0d1725}
.jb-list{list-style:none;margin:0 0 6px;padding:0;text-align:left;display:grid;gap:9px}
.jb-list li{position:relative;padding-left:26px;font:600 15px/1.35 system-ui,sans-serif;color:#0d1725}
.jb-list li::before{content:'\221e';position:absolute;left:0;top:-1px;color:#e0a100;font:900 18px/1.2 system-ui,sans-serif}
.jb-plus{margin:14px 0 8px;text-align:left;color:#5b6b80;font:800 11px/1.2 system-ui,sans-serif;letter-spacing:.08em;text-transform:uppercase}
.jb-tools li{font-weight:500;color:#33445a}
.jb-tools li::before{content:'\2713';color:#1f9d55;font-size:15px;top:0}
.jb-go{display:block;width:100%;margin-top:18px;padding:17px 0;border:0;border-radius:14px;background:#ffc13d;color:#1b1400;
  font:900 23px/1 system-ui,sans-serif;letter-spacing:.04em;cursor:pointer;box-shadow:0 5px 0 #c98a00}
.jb-go:active{transform:translateY(3px);box-shadow:0 2px 0 #c98a00}
.jb-sub{margin:14px 0 0;color:#5b6b80;font:500 13px/1.3 system-ui,sans-serif}
.jb-sub a{color:#8a5a06;font-weight:800}
@keyframes jb-in{from{opacity:0}to{opacity:1}}

/* ======================================================================
   WORKS LIKE INSTAGRAM (27 Sep 2026) -- see the block of the same name in
   feed.js.
   ====================================================================== */
body{overscroll-behavior-y:contain}              /* our pull-to-refresh, not the browser's */
.post .rail figure{touch-action:manipulation}     /* no zoom fighting the double-tap */
.caption > b:first-child[data-open-person],.caption > b:first-child[data-open-shop],
.mention,.soc-heat b[data-open-person],.soc-last b[data-open-person]{cursor:pointer}
.mention{color:var(--gold);font-weight:700}
.soc-heat{margin:2px 13px 0;font-size:13.5px;line-height:1.4;color:var(--text)}
.soc-heat b{font-weight:800}
.soc-heat b[data-open-person]{color:var(--gold)}
.soc-talk{margin:2px 13px 4px}
.soc-all{padding:2px 0;border:0;background:none;color:var(--dim);font:500 13.5px/1.4 system-ui,sans-serif;cursor:pointer}
.soc-last{margin:1px 0 0;font-size:13.5px;line-height:1.4;color:var(--text);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.soc-last b[data-open-person]{color:var(--gold);font-weight:700}

/* the flame that pops on a double-tap */
.frame{position:relative}
.dt-burst{position:absolute;z-index:6;width:150px;height:188px;margin:-94px 0 0 -75px;pointer-events:none;
  filter:drop-shadow(0 6px 18px rgba(0,0,0,.45));transform-origin:50% 60%;
  animation:dt-pop 1s cubic-bezier(.2,1.3,.4,1) forwards}
.dt-burst svg{width:100%;height:100%;display:block}
/* Instagram's heart: pops in past full size, settles, holds, then shrinks away. */
@keyframes dt-pop{
  0%{transform:scale(0);opacity:0}
  15%{transform:scale(1.25);opacity:1}
  30%{transform:scale(.92)}
  45%{transform:scale(1.05)}
  75%{transform:scale(1);opacity:1}
  100%{transform:scale(.2);opacity:0}}

/* followers / following list */
.flist{position:fixed;inset:0;z-index:200;display:flex;align-items:flex-end;justify-content:center;
  background:rgba(2,4,10,.6);animation:jb-in .18s ease-out}
.fl-card{width:100%;max-width:480px;max-height:78vh;display:flex;flex-direction:column;background:#fff;color:#0d1725;
  border-radius:18px 18px 0 0;overflow:hidden}
.fl-top{padding:14px 16px 10px;text-align:center;border-bottom:1px solid #e3e8ef;font:800 16px/1.2 system-ui,sans-serif}
.fl-top::before{content:'';display:block;width:40px;height:4px;margin:-4px auto 10px;border-radius:2px;background:#cfd6e0}
.fl-rows{overflow-y:auto;padding:6px 0 max(14px,env(safe-area-inset-bottom))}
.fl-row{display:flex;align-items:center;gap:12px;width:100%;padding:9px 16px;border:0;background:none;text-align:left;cursor:pointer;color:inherit}
.fl-row img{width:44px;height:44px;border-radius:50%;object-fit:cover;flex:0 0 auto;background:#eef2f6}
.fl-row span{display:flex;flex-direction:column;min-width:0}
.fl-row b{font:700 14.5px/1.3 system-ui,sans-serif;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fl-row small{font:500 13px/1.3 system-ui,sans-serif;color:#5b6b80;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fl-wait{margin:18px 16px;color:#5b6b80;text-align:center;font-size:14px}

/* pull to refresh */
.ptr{position:fixed;left:50%;top:calc(var(--stick,60px) + 4px);z-index:40;width:34px;height:34px;border-radius:50%;
  background:var(--panel);border:1px solid var(--line);box-shadow:0 4px 14px rgba(0,0,0,.35);
  transform:translate(-50%,-80px);pointer-events:none;display:grid;place-items:center;
  opacity:0}   /* invisible until a pull starts -- it was peeking out under the top bar */
.ptr span{width:16px;height:16px;border-radius:50%;border:2.5px solid var(--dim);border-top-color:transparent}
.ptr.ready span{border-color:var(--gold);border-top-color:transparent}
.ptr.spin span{animation:ptr-spin .7s linear infinite}
@keyframes ptr-spin{to{transform:rotate(360deg)}}

/* ======================================================================
   THE RAIL (27 Sep 2026) -- ME · GOALS · NEW POSTS · ALERTS, right under
   the top bar, Facebook-style. See buildRail() in feed.js.
   ====================================================================== */
.fbrail{display:grid;grid-template-columns:repeat(4,1fr);background:var(--panel);
  border-bottom:1px solid var(--line)}
.fbrail > *{position:relative;display:flex;flex-direction:column;align-items:center;gap:3px;
  padding:8px 0 7px;border:0;background:none;cursor:pointer;text-decoration:none;
  color:var(--dim);font:800 10px/1 system-ui,sans-serif;letter-spacing:.05em}
.fbrail > *.on{color:var(--text);box-shadow:inset 0 -3px 0 var(--gold)}
.fbrail svg{width:24px;height:24px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.fbrail > *:active svg{transform:scale(.9)}
.rb-n{position:absolute;top:3px;left:calc(50% + 5px);min-width:18px;height:18px;padding:0 5px;box-sizing:border-box;
  border-radius:9px;background:#ff3b30;color:#fff;font:800 11px/18px system-ui,sans-serif;font-style:normal;
  text-align:center;border:2px solid var(--panel)}
.rb-n[hidden]{display:none}

/* ======================================================================
   GOALS, AS A FEED (27 Sep 2026) -- see openGoals() in feed.js.
   ====================================================================== */
.feed.is-goals > :not(#goalsview){display:none}
#goalsview{display:flex;flex-direction:column;gap:14px;padding:12px 0 20px}
.gv-h{margin:6px 14px 0;font:900 13px/1 system-ui,sans-serif;letter-spacing:.12em;text-transform:uppercase;color:var(--dim)}
.goalcard{margin:0 10px;border:1px solid var(--line);border-radius:16px;background:var(--panel);overflow:hidden}
.goalcard.is-done{border-color:var(--gold);box-shadow:0 0 0 1px var(--gold) inset}
.gc-top{display:flex;align-items:center;gap:10px;padding:12px 13px}
.gc-icon{width:44px;height:44px;flex:0 0 auto;border-radius:12px;background:var(--panel-2,#12203a);display:grid;place-items:center;font-size:24px;overflow:hidden}
.gc-icon img{width:100%;height:100%;object-fit:cover}
.gc-name{display:flex;flex-direction:column;min-width:0;flex:1}
.gc-name b{font:800 16px/1.2 system-ui,sans-serif;color:var(--text)}
.gc-name small{font:500 12.5px/1.35 system-ui,sans-serif;color:var(--dim);margin-top:2px}
.gc-tag{flex:0 0 auto;padding:4px 8px;border-radius:6px;background:var(--gold);color:#1b1400;font:900 10px/1 system-ui,sans-serif;letter-spacing:.08em}
.gc-body{display:flex;align-items:center;gap:16px;padding:6px 16px 12px}
.gc-dial{position:relative;width:104px;height:104px;flex:0 0 auto}
.gc-ring{width:100%;height:100%;transform:rotate(-90deg)}
.gc-track{fill:none;stroke:var(--line);stroke-width:12}
.gc-fill{fill:none;stroke:var(--gold);stroke-width:12;stroke-linecap:round;transition:stroke-dasharray .6s ease}
.gc-pct{position:absolute;inset:0;display:grid;place-items:center;font:900 24px/1 system-ui,sans-serif;color:var(--text)}
.goalcard.is-done .gc-pct{color:var(--gold);font-size:40px}
.gc-facts{display:flex;flex-direction:column;gap:5px;min-width:0;flex:1}
.gc-facts b{font:900 20px/1.1 system-ui,sans-serif;color:var(--text)}
.gc-facts span{font:600 13px/1.35 system-ui,sans-serif;color:var(--dim)}
.gc-bar{display:block;height:8px;border-radius:4px;background:var(--line);overflow:hidden}
.gc-bar i{display:block;height:100%;background:var(--gold);border-radius:4px}
.gc-next{padding:0 13px 10px}
.gc-next small{font:900 10px/1 system-ui,sans-serif;letter-spacing:.1em;color:var(--dim)}
.gc-next div{display:flex;gap:4px;margin-top:6px;overflow:hidden}
.gc-next img{width:40px;height:40px;image-rendering:pixelated;filter:grayscale(1) brightness(.8);opacity:.75}
.gc-acts{display:flex;gap:8px;flex-wrap:wrap;padding:10px 13px 13px;border-top:1px solid var(--line)}
.gc-acts button{flex:1;min-width:0;padding:10px 12px;border-radius:10px;border:1px solid var(--line);background:none;
  color:var(--text);font:700 13px/1 system-ui,sans-serif;cursor:pointer}
.gc-acts .gc-drop{flex:0 0 auto;color:var(--dim)}
.gc-add{background:var(--gold)!important;border-color:var(--gold)!important;color:#1b1400!important;font-weight:900!important}
.gc-own{display:flex;gap:8px;padding:0 13px 13px}
.gc-own input{min-width:0;flex:1;padding:10px 11px;border-radius:10px;border:1px solid var(--line);background:var(--ink);color:var(--text);font:500 14px/1.2 system-ui,sans-serif}
.gc-own input[type=number]{flex:0 0 96px}
.gc-own button{flex:0 0 auto;padding:10px 14px;border-radius:10px;border:0;cursor:pointer}
.pg-goals{grid-column:1/-1;display:flex;flex-direction:column;gap:12px;padding:10px 0}

/* ---- Social pack 1: the ⋯ menu, report/block sheet, edit caption, views ---- */
.post-top { position: relative; }
.post-more { margin-left: auto; flex: 0 0 auto; width: 36px; height: 36px; display: grid; place-items: center;
  background: none; border: 0; padding: 0; color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.post-more svg { width: 20px; height: 20px; fill: currentColor; opacity: .75; }
.more-rows { padding: 4px 0 8px; }
.more-row { display: block; width: 100%; text-align: left; background: none; border: 0; border-top: 1px solid rgba(127,127,127,.18);
  padding: 15px 18px; font: inherit; font-size: 16px; color: inherit; cursor: pointer; }
.more-row:first-child { border-top: 0; }
.more-row.is-warn { color: #e0245e; font-weight: 600; }
.cap-edit { margin: 6px 12px 10px; }
.cap-edit textarea { width: 100%; box-sizing: border-box; font: inherit; font-size: 16px; padding: 10px 12px;
  border-radius: 12px; border: 1px solid rgba(127,127,127,.35); background: transparent; color: inherit; resize: vertical; }
.cap-edit div { display: flex; justify-content: flex-end; gap: 10px; margin-top: 8px; }
.cap-edit button { font: inherit; font-weight: 700; border: 0; border-radius: 999px; padding: 9px 18px; cursor: pointer;
  background: rgba(127,127,127,.18); color: inherit; }
.cap-edit button[type="submit"] { background: #0095f6; color: #fff; }
.soc-views { opacity: .7; }
.soc-dot { font-style: normal; opacity: .5; }
.ip-toast { position: fixed; left: 50%; bottom: calc(84px + env(safe-area-inset-bottom)); transform: translate(-50%, 20px);
  background: #262626; color: #fff; padding: 11px 18px; border-radius: 999px; font-size: 14px; font-weight: 600;
  max-width: calc(100vw - 32px); text-align: center; opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s; z-index: 10050; }
.ip-toast.on { opacity: 1; transform: translate(-50%, 0); }

/* ---- Notifications nudge ---- */
.pushask .fl-card { padding: 0; }
.pa-body { padding: 22px 22px calc(18px + env(safe-area-inset-bottom)); text-align: center; font-family: system-ui, sans-serif; }
.pa-bell { font-size: 44px; line-height: 1; margin-bottom: 8px; }
.pa-body h3 { margin: 0 0 6px; font: 800 21px/1.2 system-ui, sans-serif; color: #0d1725; }
.pa-body p { margin: 0 0 16px; font-size: 15.5px; line-height: 1.4; color: #3b4658; }
.pa-body ol { text-align: left; margin: 0 0 16px; padding-left: 22px; font-size: 15px; line-height: 1.5; color: #0d1725; }
.pa-body ol li { margin-bottom: 6px; }
.pa-share { display: inline-block; padding: 0 5px; border: 1.5px solid #0095f6; border-radius: 5px; color: #0095f6; font-size: 12px; }
.pa-go { display: block; width: 100%; border: 0; border-radius: 14px; padding: 16px; font: 900 18px/1 system-ui, sans-serif; letter-spacing: .04em;
  color: #fff; background: linear-gradient(135deg, #ff8a00, #e52e71); cursor: pointer; }
.pa-go:disabled { opacity: .7; }
.pa-no { display: block; width: 100%; margin-top: 8px; border: 0; background: none; padding: 12px; font: 600 15px/1 system-ui, sans-serif; color: #6b7686; cursor: pointer; }

/* ---- Hot this week ---- */
.hotwk { margin: 6px 0 10px; }
.hw-head { padding: 4px 13px 8px; font: 900 13px/1 system-ui, sans-serif; letter-spacing: .08em; color: var(--text); }
.hw-row { display: flex; gap: 9px; overflow-x: auto; padding: 0 13px 4px; scroll-snap-type: x mandatory; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.hw-row::-webkit-scrollbar { display: none; }
.hw-tile { position: relative; flex: 0 0 116px; height: 156px; padding: 0; border: 0; border-radius: 14px; overflow: hidden;
  background: #1b2433; cursor: pointer; scroll-snap-align: start; box-shadow: 0 0 0 2px #ff7a18 inset; }
.hw-tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hw-rank { position: absolute; top: 6px; left: 7px; min-width: 22px; height: 22px; padding: 0 5px; border-radius: 11px; display: grid; place-items: center;
  font: 900 12px/1 system-ui, sans-serif; color: #fff; background: linear-gradient(135deg, #ff8a00, #e52e71); }
.hw-foot { position: absolute; left: 0; right: 0; bottom: 0; padding: 18px 7px 7px; text-align: left;
  background: linear-gradient(transparent, rgba(0,0,0,.8)); color: #fff; font: 12px/1.25 system-ui, sans-serif; }
.hw-foot b { display: block; font-weight: 800; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hw-foot i { font-style: normal; opacity: .9; }
.hotview { position: fixed; inset: 0; z-index: 190; background: rgba(0,0,0,.82); overflow-y: auto; -webkit-overflow-scrolling: touch;
  display: flex; align-items: flex-start; justify-content: center; padding: calc(24px + env(safe-area-inset-top)) 0 40px; }
.hv-card { width: 100%; max-width: 520px; background: var(--ink); border-radius: 16px; overflow: hidden; }

/* ---- Streaks ---- */
.ph-chips { flex-wrap: wrap; }
.ph-streak { font: 800 12px/1.2 system-ui, sans-serif; color: #fff; padding: 6px 11px; border-radius: 999px;
  background: linear-gradient(135deg, #ff8a00, #e52e71); }
.ph-streak.is-risk { background: none; color: #ffb35c; box-shadow: 0 0 0 1.5px #ff8a00 inset; }

/* ---- Share to story ---- */
.share-story small { display: block; margin-top: 3px; font-size: 13px; font-weight: 500; opacity: .6; }
.share-story:disabled { cursor: default; }
.share-story:disabled { opacity: .75; }

/* ---- Invites ---- */
.pbtn.is-invite { background: linear-gradient(135deg, #ff8a00, #e52e71); color: #fff; border-color: transparent; }
.ph-inv { font: 800 12px/1.2 system-ui, sans-serif; color: var(--text); padding: 6px 11px; border-radius: 999px; border: 1px solid var(--line); }

/* ---- Notifications dropdown (the bell) -- A+ look, 27 Sep 2026 ---- */
.bell .slash { display: none !important; }
.bell svg { stroke: var(--text); }
.bell-n { position: absolute; top: -3px; right: -4px; min-width: 19px; height: 19px; padding: 0 5px; border-radius: 10px;
  background: #e41e3f; color: #fff; font: 800 11px/19px system-ui, sans-serif; font-style: normal; text-align: center;
  box-shadow: 0 0 0 2px var(--ink); pointer-events: none; }
.bell-n[hidden] { display: none; }
.notifdrop { position: fixed; left: 0; right: 0; top: var(--nd-top, 56px); bottom: 0; z-index: 180; background: rgba(0,0,0,.55);
  animation: ndFade .15s ease-out; padding: 6px 8px 0; }
.nd-panel { max-width: 560px; margin: 0 auto; max-height: calc(100% - 18px); overflow-y: auto; -webkit-overflow-scrolling: touch;
  background: #fff; color: #0d1725; border-radius: 18px; box-shadow: 0 20px 50px rgba(0,0,0,.5);
  animation: ndDrop .2s cubic-bezier(.2,.9,.3,1.1); font-family: system-ui, sans-serif; }
@keyframes ndDrop { from { transform: translateY(-14px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes ndFade { from { opacity: 0; } to { opacity: 1; } }
.nd-holo { position: sticky; top: 0; z-index: 2; height: 6px;
  background: linear-gradient(90deg, #ff8a00, #ffd23f, #3ee0a4, #39b8ff, #a970ff, #e52e71, #ff8a00); background-size: 200% 100%;
  animation: ndHolo 6s linear infinite; }
@keyframes ndHolo { to { background-position: 200% 0; } }
.nd-head { position: sticky; top: 6px; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 14px 16px 8px; background: #fff; }
.nd-head b { display: flex; align-items: center; gap: 8px; font: 900 23px/1 system-ui, sans-serif; color: #0d1725; }
.nd-head b em { font-style: normal; font-size: 24px; background: linear-gradient(135deg, #ff8a00, #e52e71); -webkit-background-clip: text; background-clip: text; color: transparent; }
.nd-phone { display: flex; align-items: center; gap: 8px; border: 0; background: none; padding: 4px 0; color: #6b7686;
  font: 700 12.5px/1.2 system-ui, sans-serif; cursor: pointer; text-align: right; white-space: nowrap; }
.nd-phone i { flex: 0 0 auto; width: 38px; height: 22px; border-radius: 11px; background: #cfd6e0; position: relative; transition: background .2s; }
.nd-phone i::after { content: ''; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; transition: transform .2s; box-shadow: 0 1px 2px rgba(0,0,0,.2); }
.nd-phone[data-state="on"] i { background: linear-gradient(135deg, #ff8a00, #e52e71); }
.nd-phone[data-state="on"] i::after { transform: translateX(16px); }
.nd-phone:disabled { opacity: .8; cursor: default; }
.nd-phone:disabled i { display: none; }
.nd-sec { margin: 0; padding: 10px 16px 4px; font: 900 12px/1 system-ui, sans-serif; letter-spacing: .16em; color: #e8590c; }
.nd-row { position: relative; display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 32px 10px 14px; border: 0;
  background: none; color: #0d1725; text-align: left; cursor: pointer; font: 16px/1.3 system-ui, sans-serif; }
.nd-row.is-new { background: #fff3e6; }
.nd-row:active { background: #f1f3f6; }
.nd-row.is-new:active { background: #ffe8d1; }
.nd-face { position: relative; flex: 0 0 54px; width: 54px; height: 54px; border-radius: 50%; display: grid; place-items: center;
  background: #eef1f5; font: 800 17px/1 system-ui, sans-serif; color: #0d1725; }
.nd-face img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.nd-row.is-new .nd-face { box-shadow: 0 0 0 2px #fff, 0 0 0 4px #ffc491; }
.nd-face.is-app svg { width: 26px; height: 26px; fill: none; stroke: #e8590c; stroke-width: 1.8; }
.nd-k { position: absolute; right: -4px; bottom: -4px; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center;
  font: 800 12px/1 system-ui, sans-serif; color: #fff; background: #2d88ff; box-shadow: 0 0 0 2px #fff; }
.nd-k-heat { background: #ff7a18; } .nd-k-follow, .nd-k-invite { background: #31a24c; font-size: 16px; }
.nd-k-mention { background: #8a3ffc; } .nd-k-heart { background: #e52e71; }
.nd-txt { flex: 1 1 auto; min-width: 0; }
.nd-line { overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.nd-line b { font-weight: 800; }
.nd-line q { quotes: '\201C' '\201D'; }
.nd-txt small { display: block; margin-top: 3px; font-size: 13px; color: #6b7686; }
.nd-row.is-new .nd-txt small { color: #e8590c; font-weight: 800; }
.nd-thumb { flex: 0 0 50px; width: 50px; height: 50px; border-radius: 8px; object-fit: cover;
  box-shadow: 0 0 0 2px #fff, 0 0 0 3.5px rgba(169,112,255,.55); }
.nd-fb { flex: 0 0 auto; padding: 9px 12px; border-radius: 10px; background: linear-gradient(135deg, #ff8a00, #e52e71);
  color: #fff; font: 800 13px/1 system-ui, sans-serif; white-space: nowrap; }
.nd-fb.is-on { background: #eef1f5; color: #0d1725; }
.nd-dot { position: absolute; right: 11px; top: 50%; margin-top: -6px; width: 12px; height: 12px; border-radius: 50%;
  background: linear-gradient(135deg, #ff8a00, #e52e71); box-shadow: 0 0 0 3px #ffe0c2; }
.nd-empty { padding: 30px 18px; text-align: center; color: #6b7686; font-size: 15px; line-height: 1.5; margin: 0; }
/* the comment a notification pointed at */
.cmt.cmt-hl { animation: cmtHl 4s ease-out; border-radius: 12px; }
@keyframes cmtHl { 0%, 60% { background: rgba(255,154,60,.22); box-shadow: 0 0 0 2px rgba(255,154,60,.6); } 100% { background: transparent; box-shadow: none; } }
/* arriving from a notification: two ways onward under the post */
.pinned-links { display: flex; flex-direction: column; gap: 2px; }

/* ---- Invite your friends ---- */
.invite .fl-card { padding: 0; }
.iv-body { padding: 22px 18px calc(18px + env(safe-area-inset-bottom)); text-align: center; font-family: system-ui, sans-serif; color: #0d1725; }
.iv-art { font-size: 46px; line-height: 1; margin-bottom: 6px; }
.iv-body h3 { margin: 0 0 6px; font: 900 22px/1.2 system-ui, sans-serif; }
.iv-body > p { margin: 0 0 16px; font-size: 15px; line-height: 1.4; color: #3b4658; }
.iv-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 12px; }
.iv-tile { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 4px 12px; border-radius: 16px;
  border: 1px solid #e3e8ef; background: #f6f8fb; font: 700 13px/1.1 system-ui, sans-serif; color: #0d1725; cursor: pointer; }
.iv-tile:active { background: #eef2f7; }
.iv-ic { font-size: 28px; line-height: 1; }
.iv-copy { display: block; width: 100%; border: 0; border-radius: 14px; padding: 15px; font: 900 16px/1 system-ui, sans-serif;
  color: #fff; background: linear-gradient(135deg, #ff8a00, #e52e71); cursor: pointer; }
.iv-count { margin: 12px 0 0; font: 700 14px/1.3 system-ui, sans-serif; color: #0d1725; }
.iv-skip { display: block; width: 100%; margin-top: 6px; border: 0; background: none; padding: 12px; font: 600 15px/1 system-ui, sans-serif; color: #6b7686; cursor: pointer; }

/* ---- More than one picture per post (27 Sep 2026) ---- */
/* The dots are <button>s (paintStrip draws them that way); they were only
   styled as <i>, so they showed up as plain grey browser buttons. */
.pips button{
  width:7px;height:7px;border-radius:50%;background:#ffffff66;transition:background .2s;
  pointer-events:auto;cursor:pointer;padding:0;
  box-sizing:content-box;border:8px solid transparent;background-clip:padding-box;margin:-8px -5px;
  box-shadow:none;
}
.pips button.on{background:var(--gold);box-shadow:none;background-clip:padding-box}
/* a photo post with several pictures: a stack mark on the grid tile, like Instagram */
.is-grid .post.is-multi .frame::after{
  content:'';position:absolute;top:7px;right:7px;width:18px;height:18px;z-index:3;pointer-events:none;
  background:no-repeat center/contain 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.2'%3E%3Crect x='7' y='3' width='14' height='14' rx='2'/%3E%3Cpath d='M17 21H5a2 2 0 0 1-2-2V7'/%3E%3C/svg%3E");
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.7));
}
.is-grid .post.is-multi .count,.is-grid .post.is-multi .pips,.is-grid .post.is-multi .nudge{display:none}

/* ---- New this week (Jeff, 27 Sep 2026) ---- */
.rail-block[data-rail="newbies"] h2{color:#ff9a3c;font-size:12px}
.rail-newbie{flex:0 0 auto;width:118px;display:flex;flex-direction:column;align-items:center;gap:5px;padding:12px 8px;
  border-radius:16px;background:var(--panel);border:1px solid var(--line);text-align:center}
.nb-face{width:74px;height:74px;padding:3px;border:0;border-radius:50%;cursor:pointer;
  background:linear-gradient(135deg,#ff8a00,#ffd23f,#e52e71)}
.nb-face img{width:100%;height:100%;border-radius:50%;object-fit:cover;display:block;border:3px solid var(--panel)}
.nb-name{max-width:100%;border:0;background:none;padding:0;cursor:pointer;color:var(--text);
  font:800 13.5px/1.2 system-ui,sans-serif;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rail-newbie small{color:var(--dimmer);font-size:11.5px}
.rail-newbie .nb-follow{margin-top:3px;width:100%;padding:7px 0;font-size:11.5px}

/* ---- Suggested for you (on at 50 members) ---- */
.rail-newbie.is-suggest{position:relative;width:132px}
.rail-newbie.is-suggest small{min-height:2.6em;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.sg-x{position:absolute;top:4px;right:6px;width:26px;height:26px;border:0;background:none;color:var(--dimmer);font:600 20px/1 system-ui,sans-serif;cursor:pointer}

/* ---- Get started (27 Sep 2026) ---- */
.getstarted{position:relative;margin:10px 10px 12px;padding:16px 14px 12px;border-radius:18px;background:#fff;color:#0d1725;
  box-shadow:0 8px 24px rgba(0,0,0,.35);font-family:system-ui,sans-serif}
.getstarted::before{content:'';position:absolute;left:0;right:0;top:0;height:5px;border-radius:18px 18px 0 0;
  background:linear-gradient(90deg,#ff8a00,#ffd23f,#3ee0a4,#39b8ff,#a970ff,#e52e71)}
.getstarted h3{margin:2px 0 8px;font:900 19px/1.1 system-ui,sans-serif;display:flex;align-items:baseline;gap:8px}
.getstarted h3 span{font:800 12px/1 system-ui,sans-serif;color:#e8590c;letter-spacing:.06em}
.gs-x{position:absolute;top:8px;right:8px;width:30px;height:30px;border:0;background:none;color:#8a94a3;font:600 22px/1 system-ui;cursor:pointer}
.gs-bar{height:6px;border-radius:3px;background:#eef1f5;overflow:hidden;margin-bottom:6px}
.gs-bar i{display:block;height:100%;border-radius:3px;background:linear-gradient(90deg,#ff8a00,#e52e71)}
.gs-step{display:flex;align-items:center;gap:12px;padding:10px 0;border-top:1px solid #eef1f5}
.gs-step:first-of-type{border-top:0}
.gs-num{flex:0 0 32px;height:32px;border-radius:50%;display:grid;place-items:center;font:900 15px/1 system-ui;color:#fff;
  background:linear-gradient(135deg,#ff8a00,#e52e71)}
.gs-step.is-done .gs-num{background:#31a24c}
.gs-txt{flex:1;min-width:0}.gs-txt b{display:block;font:800 15px/1.25 system-ui}
.gs-txt small{display:block;margin-top:2px;font-size:12.5px;color:#6b7686}
.gs-step.is-done .gs-txt b{color:#6b7686;text-decoration:line-through}
.gs-go{flex:0 0 auto;border:0;border-radius:10px;padding:10px 14px;font:900 13px/1 system-ui;letter-spacing:.04em;color:#fff;cursor:pointer;
  background:linear-gradient(135deg,#ff8a00,#e52e71)}
.gs-ok{flex:0 0 auto;font:800 12px/1 system-ui;color:#31a24c}

/* ---- Profile score (27 Sep 2026) ---- */
.ps-top{display:flex;align-items:center;gap:14px;margin:2px 26px 8px 0}
.ps-top h3{margin:0 0 3px;font:900 18px/1.2 system-ui,sans-serif;color:#0d1725;display:block}
.ps-top small{font-size:12.5px;color:#6b7686}
.ps-ring{flex:0 0 auto}
.ps-all{display:block;width:100%;margin-top:4px;padding:10px;border:0;background:none;font:800 13px/1 system-ui,sans-serif;
  letter-spacing:.06em;color:#e8590c;cursor:pointer}
.pscheck .fl-card{padding:0}
.ps-body{padding:20px 16px calc(16px + env(safe-area-inset-bottom));font-family:system-ui,sans-serif;color:#0d1725}
.ph-score{border:0;border-radius:999px;padding:6px 12px;font:800 12px/1.2 system-ui,sans-serif;color:#fff;cursor:pointer;
  background:linear-gradient(135deg,#ff8a00,#e52e71)}

/* ---- Say hi + Say welcome (27 Sep 2026) ---- */
.nm-tag{margin-left:auto;flex:0 0 auto;padding:5px 9px;border-radius:999px;font:900 10px/1 system-ui,sans-serif;letter-spacing:.08em;
  color:#fff;background:linear-gradient(135deg,#31a24c,#3ee0a4)}
.nm-tag + .post-more{margin-left:4px}
.welcome-btn{display:block;width:calc(100% - 24px);margin:2px 12px 8px;padding:13px;border:0;border-radius:12px;cursor:pointer;
  background:#fff;color:#0d1725;font:900 15px/1 system-ui,sans-serif}
.welcome-btn.is-done{background:transparent;color:#7f93b3;box-shadow:inset 0 0 0 1px var(--line);cursor:default}
.sayhi{position:fixed;inset:0;z-index:200;background:#04070f;color:#e9f0fa;display:flex;flex-direction:column;font-family:system-ui,sans-serif}
.sh-top{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;padding:calc(12px + env(safe-area-inset-top)) 14px 10px;border-bottom:1px solid var(--line-soft)}
.sh-top button{justify-self:start;border:0;background:none;color:#9fb3d1;font:600 15px system-ui;cursor:pointer;padding:6px 0}
.sh-top b{font:800 16px system-ui}
.sh-scroll{flex:1;overflow-y:auto;padding:12px 14px calc(20px + env(safe-area-inset-bottom));max-width:520px;width:100%;margin:0 auto;box-sizing:border-box}
.sh-hint{margin:2px 0 12px;font:600 15px/1.4 system-ui;color:#c9d6ea;text-align:center}
.sh-pic{border-radius:16px;overflow:hidden;background:#0b1322;aspect-ratio:4/5;display:grid;place-items:center}
.sh-pic img{width:100%;height:100%;object-fit:cover;display:block}
.sh-wait{color:#7f93b3;font:600 14px system-ui;padding:20px;text-align:center}
.sh-cap{display:block;width:100%;box-sizing:border-box;margin:12px 0 10px;padding:12px;border-radius:12px;border:1px solid rgba(255,255,255,.2);
  background:transparent;color:#fff;font:16px/1.4 system-ui;resize:none}
.sh-go{display:block;width:100%;padding:16px;border:0;border-radius:14px;cursor:pointer;color:#fff;font:900 17px/1 system-ui;letter-spacing:.04em;
  background:linear-gradient(135deg,#ff8a00,#e52e71)}
.sh-go:disabled{opacity:.6}
.sh-alt{display:block;width:100%;margin-top:10px;padding:14px;border:0;border-radius:14px;background:#fff;color:#0d1725;font:800 15px system-ui;cursor:pointer}
.sh-small{margin:10px 0 0;text-align:center;color:#7f93b3;font:600 13px system-ui}
.sh-say{margin:0 0 10px;color:#fca5a5;font:700 13px/1.4 system-ui}
.sh-yay{font-size:64px;text-align:center;margin-top:30px}
.sh-h{margin:6px 0 4px;text-align:center;font:900 26px system-ui;color:#fff}

/* ---- Collectr + Dex buttons on profiles (27 Sep 2026) ---- */
.ph-soc{flex-wrap:wrap;align-items:center}
.psoc.psoc-app{width:auto;height:34px;border-radius:999px;padding:0 12px 0 9px;display:inline-flex;gap:6px;
  font:800 12px/1 system-ui,sans-serif;color:var(--text);text-decoration:none}

/* ---- (i) how-tos on Edit profile ---- */
.ep-info{display:inline-grid;place-items:center;width:18px;height:18px;margin-left:6px;border-radius:50%;vertical-align:1px;cursor:pointer;
  background:#2d88ff;color:#fff;font:italic 800 12px/1 Georgia,serif}
.ep-info.on{background:#e8590c}
.ep-help{margin:-4px 0 12px;padding:12px 14px;border-radius:12px;background:rgba(45,136,255,.1);border:1px solid rgba(45,136,255,.35);
  font:14px/1.45 system-ui,sans-serif}
.ep-help[hidden]{display:none}
.ep-help ol{margin:6px 0 6px;padding-left:20px}
.ep-help small{display:block;opacity:.75;font-size:12.5px}

/* ---- Bring your collection in (27 Sep 2026) ---- */
.pimport{display:flex;align-items:center;gap:12px;margin:8px 10px 10px;padding:14px 16px;border-radius:14px;text-decoration:none;color:#fff;
  background:linear-gradient(135deg,#ff8a00,#e52e71);box-shadow:0 6px 18px rgba(229,46,113,.3)}
.pimport-ic{font-size:26px;line-height:1}
.pimport b{display:block;font:900 15px/1.2 system-ui,sans-serif;letter-spacing:.04em}
.pimport small{display:block;margin-top:2px;font:600 12.5px/1.3 system-ui,sans-serif;opacity:.9}
.gs-btns{display:flex;gap:6px;flex:0 0 auto}
.gs-go.gs-alt{background:#fff;color:#e8590c;box-shadow:inset 0 0 0 2px #ff8a00}

/* @ PICKER (27 Sep 2026) -- the list of collectors above a comment or caption box. */
.mention-pick{display:flex;flex-direction:column;margin:0 0 6px;background:#fff;border:1px solid rgba(0,0,0,.12);border-radius:14px;box-shadow:0 6px 22px rgba(0,0,0,.14);overflow:hidden;max-height:260px;overflow-y:auto}
.mention-pick .mp-row{display:flex;align-items:center;gap:10px;width:100%;padding:9px 12px;border:0;background:none;text-align:left;font:inherit;font-size:15px;font-weight:700;color:#111;cursor:pointer;min-height:44px}
.mention-pick .mp-row+.mp-row{border-top:1px solid rgba(0,0,0,.06)}
.mention-pick .mp-row.on,.mention-pick .mp-row:active{background:#fff3ea}
.mention-pick img,.mention-pick .mp-face{width:30px;height:30px;border-radius:50%;object-fit:cover;flex:none}
.mention-pick .mp-face{display:grid;place-items:center;background:linear-gradient(135deg,#ff7a2f,#ff3d7f);color:#fff;font-size:13px}

/* THE SOFT WALL (27 Sep 2026) -- after a guest's first 9 posts or cards on a profile. */
.guest-wall{margin:14px 12px 28px;padding:22px 18px 18px;border-radius:18px;text-align:center;
  background:#fff;color:#111;box-shadow:0 8px 28px rgba(0,0,0,.28);position:relative;overflow:hidden}
.guest-wall::before{content:"";position:absolute;left:0;right:0;top:0;height:5px;
  background:linear-gradient(90deg,#ff7a2f,#ff3d7f,#7c5cff,#19bfff,#35d07f,#ffc13d)}
.pgrid .guest-wall{grid-column:1/-1;margin:14px 10px 28px}
.gw-face{width:64px;height:64px;border-radius:50%;object-fit:cover;display:block;margin:4px auto 10px;
  border:3px solid #ff7a2f}
.gw-h{margin:0;font-size:1.25rem;line-height:1.25;font-weight:900;overflow-wrap:anywhere}
.gw-p{margin:8px 0 0;font-size:.95rem;line-height:1.45;color:#444}
.gw-go{display:block;width:100%;margin-top:16px;padding:16px 0;border:0;border-radius:14px;
  background:linear-gradient(135deg,#ff7a2f,#ff3d7f);color:#fff;font:inherit;font-weight:900;
  font-size:1rem;letter-spacing:.04em;cursor:pointer;min-height:52px}
.gw-sub{margin:12px 0 0;font-size:.85rem;color:#666}
.gw-sub a{color:#ff3d7f;font-weight:800}

/* PHOTOS GRID (27 Sep 2026) -- three across, cropped, like Instagram's 3:4 tiles. */
.pg-tile.ph-tile{aspect-ratio:3/4}
.pg-tile.ph-tile img{width:100%;height:100%;object-fit:cover}
.ph-multi{position:absolute;top:6px;right:6px;width:18px;height:18px;pointer-events:none;
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}
.ph-multi::before,.ph-multi::after{content:"";position:absolute;border:2px solid #fff;border-radius:3px}
.ph-multi::before{inset:0 4px 4px 0}
.ph-multi::after{inset:4px 0 0 4px;border-left-color:transparent;border-top-color:transparent}
.pgrid .pg-empty b{color:var(--gold,#ffc928)}

/* ONLINE DOTS (27 Sep 2026) -- green dot on a picture when that person is active. */
.avatar-btn.is-on,.ph-ring.is-on{position:relative}
.avatar-btn.is-on::after{content:"";position:absolute;right:-1px;bottom:-1px;width:11px;height:11px;
  border-radius:50%;background:#35d07f;border:2px solid var(--bg,#03070d)}
.ph-ring.is-on::after{content:"";position:absolute;right:4px;bottom:4px;width:18px;height:18px;
  border-radius:50%;background:#35d07f;border:3px solid var(--bg,#03070d)}
.ph-active{margin:2px 0 4px;font:700 12px/1.2 system-ui,sans-serif;color:var(--muted,#9eb0c8)}
.ph-active.now{color:#35d07f}

/* SMART TAGS (27 Sep 2026) -- tappable labels under every card post. */
.stags{display:flex;flex-wrap:wrap;gap:6px;padding:8px 14px 2px}
.stag{font:700 12px/1 system-ui,sans-serif;padding:7px 11px;border-radius:999px;cursor:pointer;
  background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.14);color:var(--text,#f7f8fb);
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-height:30px}
.stag.lead{background:rgba(25,191,255,.16);border-color:rgba(25,191,255,.45);color:#7fdcff}
.stag:active{opacity:.6}
.hashtag{color:#7fdcff;font-weight:700;cursor:pointer}
.res-tags{display:flex;flex-wrap:wrap;gap:6px;padding:4px 14px 10px}

/* # PICKER (27 Sep 2026) -- tag suggestions share the @ list. */
.mention-pick .mp-hash{background:linear-gradient(135deg,#19bfff,#7c5cff);font-size:15px}
.mention-pick .mp-n{margin-left:auto;font-weight:600;font-size:12px;color:#8a97a8}
.gw-alt{display:block;width:100%;margin-top:10px;padding:14px 0;border-radius:14px;border:1.5px solid #e1e6ee;
  background:#fff;color:#111;font:inherit;font-weight:900;font-size:.95rem;letter-spacing:.04em;cursor:pointer;min-height:48px}
.gw-hint{margin:10px 0 0;padding:10px 12px;border-radius:12px;background:#fff3ea;color:#5a3a1a;font-size:.9rem;line-height:1.45;text-align:left}
