/* =====================================================================
   Strictly·Cash: spatial / cinematic layer.
   Presentation only. It never changes a colour token: it reads the existing ones (--card, --bg, --green, --ink …)
   and adds light, depth, motion and texture on top.
   ===================================================================== */

/* ---------- Motion: one high-tension curve for everything structural ---------- */
:root {
  --ease: cubic-bezier(0.19, 1, 0.22, 1);
  --spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
  --fx-ease: cubic-bezier(0.19, 1, 0.22, 1);
  --fx-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
  --fx-dur: 700ms;
  --fx-hi: rgba(255, 255, 255, 0.22);   /* edge light, dark surfaces */
  --fx-lo: rgba(255, 255, 255, 0.08);
}
:root:not([data-theme="dark"]) { --fx-hi: rgba(10, 10, 10, 0.16); --fx-lo: rgba(10, 10, 10, 0.05); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --fx-hi: rgba(255, 255, 255, 0.22); --fx-lo: rgba(255, 255, 255, 0.08); } }
:root[data-theme="dark"] { --fx-hi: rgba(255, 255, 255, 0.22); --fx-lo: rgba(255, 255, 255, 0.08); }
@property --bl-r { syntax: "<number>"; inherits: true; initial-value: 36; }
@property --bl-g { syntax: "<number>"; inherits: true; initial-value: 138; }
@property --bl-b { syntax: "<number>"; inherits: true; initial-value: 61; }

/* structural surfaces move on the long curve; press feedback keeps its short duration but uses the same curve */
.sheet, .sheet-backdrop { transition-duration: var(--fx-dur); }
.card, .item, .chip, .btn { transition-timing-function: var(--fx-ease); }
.item, .card.lift { transition: transform var(--fx-dur) var(--fx-ease), box-shadow var(--fx-dur) var(--fx-ease), opacity var(--fx-dur) var(--fx-ease); }

/* ---------- Grain: a very fine matte texture over the whole canvas ---------- */
.fx-grain { position: fixed; inset: 0; z-index: 2; pointer-events: none; opacity: 0.015;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }

/* ---------- Surface bleed: ambient colour that follows the drop in view ---------- */
.fx-bleed { position: fixed; inset: -10% -10% auto -10%; height: 70vh; z-index: -1; pointer-events: none;
  background:
    radial-gradient(55vmax 32vmax at 50% 0%, rgb(var(--bl-r) var(--bl-g) var(--bl-b) / 0.16), transparent 70%),
    radial-gradient(30vmax 22vmax at 85% 12%, rgb(var(--bl-r) var(--bl-g) var(--bl-b) / 0.09), transparent 72%);
  transition: --bl-r 1.2s var(--fx-ease), --bl-g 1.2s var(--fx-ease), --bl-b 1.2s var(--fx-ease); }

/* ---------- Contextual underglow: cards are lit from inside, not painted on ---------- */
.item[data-glow] {
  box-shadow:
    0 1px 2px rgb(0 0 0 / 0.04),
    0 14px 30px -14px rgb(var(--glow) / 0.34),
    0 34px 70px -26px rgb(var(--glow) / 0.28),
    0 60px 120px -50px rgb(var(--glow) / 0.2);
}
.item[data-glow]:hover {
  box-shadow:
    0 1px 2px rgb(0 0 0 / 0.05),
    0 18px 38px -14px rgb(var(--glow) / 0.46),
    0 44px 90px -26px rgb(var(--glow) / 0.36),
    0 80px 150px -50px rgb(var(--glow) / 0.26);
}

/* ---------- Fresnel edge: the stroke brightens where light meets it ---------- */
.card, .item, .btn-primary, .btn-dark { position: relative; --mx: 50%; --my: 0%; }
.card::after, .item::after, .btn-primary::after, .btn-dark::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px; pointer-events: none; z-index: 3;
  background:
    radial-gradient(260px circle at var(--mx) var(--my), var(--fx-hi), var(--fx-lo) 38%, transparent 72%),
    conic-gradient(from var(--fx-ang, 200deg) at 50% 50%, var(--fx-lo), transparent 24%, transparent 76%, var(--fx-lo));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  opacity: 0.75; transition: opacity var(--fx-dur) var(--fx-ease);
}
.card:hover::after, .item:hover::after, .btn-primary:hover::after, .btn-dark:hover::after { opacity: 1; }
.sheet { box-shadow: var(--shadow-float), inset 0 1px 0 var(--fx-lo); }

/* ---------- Command layering (desktop): the page recedes beneath the active layer ---------- */
/* The independent scale/translate properties are used so they never fight the page's own entry animation */
main, .topbar, .side, .tabbar { transition: transform var(--fx-dur) var(--fx-ease), filter var(--fx-dur) var(--fx-ease), scale var(--fx-dur) var(--fx-ease), translate var(--fx-dur) var(--fx-ease); transform-origin: 50% 0; }
body.fx-deck main, body.fx-deck .topbar, body.fx-deck .side { scale: 0.96; }
body.fx-deck .topbar, body.fx-deck .side, body.fx-deck .tabbar { filter: brightness(0.82); }
.sheet-backdrop { background: rgba(0, 0, 0, 0.3); }
body.fx-deck .sheet-backdrop { background: rgba(0, 0, 0, 0.4); }

/* ---------- Phone: the ribbon deck. Panels slide in horizontally on a spring, leaving a 2px sliver of the page ---------- */
@media (max-width: 759px) {
  .sheet {
    top: 0; bottom: 0; left: 2px; right: 0; max-height: none; height: 100dvh;
    border-radius: var(--r-xl) 0 0 var(--r-xl);
    padding: calc(14px + env(safe-area-inset-top, 0px)) 18px calc(24px + var(--safe-b));
    transform: translateX(104%);
    transition: transform var(--fx-dur) var(--fx-spring);
  }
  .sheet.open { transform: translateX(0); }
  .sheet-grabber { display: none; }
  body.fx-deck main, body.fx-deck .topbar { scale: 0.95; translate: -16px 0; transform-origin: 0 50%; }
}

/* ---------- Kinetic ribbons: horizontal weight and momentum for secondary rows ---------- */
.ribbon { display: flex; flex-wrap: nowrap; gap: 8px; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity;
  scrollbar-width: none; -webkit-overflow-scrolling: touch; cursor: grab; touch-action: pan-x pan-y;
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 26px), transparent 100%);
  mask-image: linear-gradient(90deg, #000 calc(100% - 26px), transparent 100%); }
.ribbon::-webkit-scrollbar { display: none; }
.ribbon > * { flex: none; scroll-snap-align: start; }
.ribbon.dragging { cursor: grabbing; scroll-snap-type: none; }
.ribbon.dragging * { pointer-events: none; }
@media (max-width: 759px) { .item .pills { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-inline: -4px; padding-inline: 4px; } .item .pills::-webkit-scrollbar { display: none; } .item .pills > * { flex: none; } }

/* ---------- Loading theatre: asymmetric sub-pixel sweeps instead of a flat pulse ---------- */
.skeleton {
  background:
    linear-gradient(104deg, transparent 32%, rgb(255 255 255 / 0.30) 44%, rgb(255 255 255 / 0.04) 50%, transparent 58%),
    linear-gradient(76deg, transparent 54%, rgb(255 255 255 / 0.14) 60%, transparent 68%),
    var(--skeleton-a);
  background-size: 260% 100%, 190% 100%, auto; background-repeat: no-repeat;
  animation: fxSweep 1.9s cubic-bezier(0.19, 1, 0.22, 1) infinite;
}
.skeleton:nth-child(even) { width: 86%; animation-duration: 2.3s; animation-delay: -0.6s; }
.skeleton:nth-child(3n) { width: 64%; animation-duration: 1.6s; }
@keyframes fxSweep { 0% { background-position: 130% 0, -70% 0, 0 0; } 100% { background-position: -130% 0, 170% 0, 0 0; } }

/* ---------- Data liquidation: figures settle like a ticker ---------- */
[data-liquid], [data-tick] { font-variant-numeric: tabular-nums; display: inline-block; transform-origin: 0 50%; }
.fx-settling { transform: scaleX(1.02);
  background-image: linear-gradient(100deg, currentColor 38%, rgb(127 127 127 / 0.45) 50%, currentColor 62%);
  background-size: 260% 100%; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  animation: fxGlint 0.9s var(--fx-ease) both; }
.fx-settled { transform: none; transition: transform 0.7s var(--fx-spring); }
@keyframes fxGlint { from { background-position: 130% 0; } to { background-position: -30% 0; } }

/* ---------- Proximity dimming: the canvas steps back when you work in one place ---------- */
body.fx-focus :is(.card, .item, .meter, .announce, .renew-banner, .progress-card, .chips, .dsearch):not(.fx-scope):not(:has(.fx-scope)) { filter: brightness(0.95); }
body.fx-focus :is(.divider, hr, .sheet-head) { border-color: transparent; }
body.fx-focus .divider { opacity: 0; }
:is(.card, .item, .meter, .announce, .chips, .divider, .dsearch) { transition: filter var(--fx-dur) var(--fx-ease), opacity var(--fx-dur) var(--fx-ease), transform var(--fx-dur) var(--fx-ease), box-shadow var(--fx-dur) var(--fx-ease); }

/* ---------- Custom vector icons: the paths themselves move ---------- */
.tab svg, .sheet-back svg, .chip-shuf svg, .ico svg { overflow: visible; }
.tab svg * { transform-box: fill-box; transition: transform var(--fx-dur) var(--fx-spring), stroke-width var(--fx-dur) var(--fx-ease); }
.tab svg { transition: stroke-width var(--fx-dur) var(--fx-ease); }
.tab:hover svg, .tab:focus-visible svg, .tab[aria-current="page"] svg { stroke-width: 2.3; }
.tab:hover { font-weight: 600; }
.tab:hover .ic-roof, .tab:focus-visible .ic-roof { transform: translateY(-1.4px); }
.tab:hover .ic-r1, .tab:focus-visible .ic-r1 { transform: translate(-0.9px, -0.9px); }
.tab:hover .ic-r2, .tab:focus-visible .ic-r2 { transform: translate(0.9px, -0.9px); }
.tab:hover .ic-r3, .tab:focus-visible .ic-r3 { transform: translate(-0.9px, 0.9px); }
.tab:hover .ic-r4, .tab:focus-visible .ic-r4 { transform: translate(0.9px, 0.9px); }
.tab .ic-bell { transform-origin: 50% 0; transform-box: fill-box; }
.tab:hover .ic-bell, .tab:focus-visible .ic-bell { transform: rotate(9deg); }
.tab:hover .ic-clap, .tab:focus-visible .ic-clap { transform: translateX(-1.6px); }
.tab:hover .ic-lid, .tab:focus-visible .ic-lid { transform: translateY(-1.6px); }
.tab:hover .ic-head, .tab:focus-visible .ic-head { transform: translateY(-1px) scale(1.12); }
.tab:hover .ic-bubble, .tab:focus-visible .ic-bubble { transform: scale(1.06) rotate(-3deg); }
.sheet-back:hover svg path, .sheet-back:focus-visible svg path { transform: translateX(-2px) scaleX(1.25); }
.sheet-back svg path { transform-box: fill-box; transform-origin: 100% 50%; transition: transform var(--fx-dur) var(--fx-spring); }
.sheet-back:hover svg, .sheet-back:focus-visible svg { stroke-width: 3; }
.chip-shuf:hover svg { transform: rotate(90deg); }

/* ---------- Search with command palette ---------- */
.drops-bar { display: flex; gap: 10px; align-items: stretch; margin: 0 0 12px; position: relative; z-index: 30; }
.dsearch { position: relative; flex: 1; min-width: 0; }
.dsearch input { width: 100%; min-height: 48px; border: 0; border-radius: var(--r-md); background: var(--fill); color: var(--ink); padding: 0 44px 0 46px; font: inherit; font-size: 16px;
  transition: background var(--fx-dur) var(--fx-ease), box-shadow var(--fx-dur) var(--fx-ease); }
.dsearch input::placeholder { color: var(--ink-3); }
.dsearch input:focus { outline: none; background: var(--card); box-shadow: 0 0 0 1.5px var(--green), 0 14px 40px -16px rgb(36 138 61 / 0.4); }
.dsearch .ico { position: absolute; left: 15px; top: 50%; margin-top: -10px; width: 20px; height: 20px; color: var(--ink-2); pointer-events: none; }
.dsearch .ico svg { width: 20px; height: 20px; }
.dsearch .ic-lens { transform-box: fill-box; transform-origin: 50% 50%; transition: transform var(--fx-dur) var(--fx-spring); }
.dsearch .ic-handle { transition: transform var(--fx-dur) var(--fx-spring), stroke-width var(--fx-dur) var(--fx-ease); }
.dsearch:focus-within .ic-lens { transform: scale(1.1); }
.dsearch:focus-within .ic-handle { transform: translate(1.4px, 1.4px); stroke-width: 2.6; }
.dsearch kbd { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); font: 600 12px/1 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--ink-3); border: 1px solid var(--line); border-radius: var(--r-xs); padding: 4px 6px; pointer-events: none; }
.dmenu { position: absolute; left: 0; right: 0; top: calc(100% + 8px); z-index: 60; background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-float);
  max-height: min(68vh, 520px); overflow-y: auto; overscroll-behavior: contain; padding: 8px; transform-origin: 50% 0; animation: fxMenu var(--fx-dur) var(--fx-ease) both; }
.dmenu[hidden] { display: none; }
@keyframes fxMenu { from { opacity: 0; transform: translateY(-8px) scale(0.98); } to { opacity: 1; transform: none; } }
.dmenu h3 { margin: 10px 10px 4px; font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.dmenu h3:first-child { margin-top: 4px; }
.dmenu [role="option"] { display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 0 12px; border-radius: var(--r-md); cursor: pointer; font-size: 15px; }
.dmenu [role="option"][aria-selected="true"], .dmenu [role="option"]:hover { background: var(--fill); }
.dmenu .dm-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dmenu .dm-s { color: var(--ink-3); font-size: 12px; }
.dmenu .dm-n { color: var(--ink-3); font-size: 12px; font-variant-numeric: tabular-nums; }
.dmenu .dm-none { padding: 14px 12px; color: var(--ink-2); font-size: 14px; }
.dmenu mark { background: none; color: var(--green); font-weight: 700; }

/* ---------- Category counters ---------- */
.chip .chip-n { margin-left: 6px; font-size: 12px; font-weight: 600; opacity: 0.6; font-variant-numeric: tabular-nums; }
.chip .chip-n::before { content: "["; opacity: 0.55; } .chip .chip-n::after { content: "]"; opacity: 0.55; }
.chip.is-zero:not([aria-pressed="true"]) { opacity: 0.38; cursor: not-allowed; }
.chip { transition: opacity var(--fx-dur) var(--fx-ease), background 0.4s var(--fx-ease), color 0.4s var(--fx-ease), transform 0.4s var(--fx-spring); }

/* ---------- Zero layout shift: a grid with locked tiles; the wrapper keeps its height while content swaps ---------- */
.feed-wrap { transition: min-height var(--fx-dur) var(--fx-ease); }
.feed { columns: auto; display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: stretch; }
@media (min-width: 560px) { .feed { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .feed { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.feed > .item { margin-bottom: 0; height: 100%; }
.feed > .item .float-img { aspect-ratio: 1 / 1; }
.feed > .item .float-img img { width: 100%; height: 100%; object-fit: contain; }
.feed.fx-in > .item { animation: fxIn var(--fx-dur) var(--fx-ease) both; animation-delay: calc(var(--k, 0) * 38ms); }
@keyframes fxIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.feed.fx-in > .item[data-reveal] { opacity: 1; }

/* ---------- Phones and tablets: the same look, built from cheaper layers ---------- */
/* Long Drops lists on iPhone ran Safari out of memory: every card carried a masked edge layer, three wide glow shadows
   and a filtered photo, all repainted while scrolling. Touch screens get one glow shadow and no edge mask or photo
   filter; cards off screen skip rendering. Photos themselves are untouched (full originals). */
.feed > .item, .lg-row { content-visibility: auto; contain-intrinsic-size: auto 480px; }
.lg-row { contain-intrinsic-size: auto 64px; }
@media (hover: none) {
  .item::after { display: none; }
  .item[data-glow] { box-shadow: 0 1px 2px rgb(0 0 0 / 0.04), 0 18px 34px -18px rgb(var(--glow) / 0.4); }
  .feed .float-img img, .lg-thumb img { filter: none; }
}

/* ---------- Filter strip (phone) and filter sheet ---------- */
.fstrip { position: fixed; left: 12px; right: 12px; bottom: calc(var(--tabbar-h) + var(--safe-b) + 10px); z-index: 38; display: none; align-items: center; gap: 10px; padding: 8px 8px 8px 12px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-float);
  transform: translateY(0); transition: transform var(--fx-dur) var(--fx-ease), opacity var(--fx-dur) var(--fx-ease); }
.fstrip.hide { transform: translateY(140%); opacity: 0; pointer-events: none; }
@media (max-width: 759px) { .fstrip { display: flex; } .drops-bar .fbtn { display: none; } main:has(.feed-wrap) { padding-bottom: calc(var(--tabbar-h) + var(--safe-b) + 96px); } }
.fstrip .fs-count { flex: 1; font-size: 14px; color: var(--ink-2); min-width: 0; white-space: nowrap; }
.fstrip .fs-count b { color: var(--ink); display: inline-block; min-width: 3ch; text-align: right; font-variant-numeric: tabular-nums; }
.fbtn { display: inline-flex; align-items: center; gap: 8px; min-height: 48px; padding: 0 18px; border: 0; border-radius: var(--r-md); background: var(--primary); color: var(--on-primary); font: inherit; font-weight: 600; cursor: pointer; }
.fbtn svg { width: 20px; height: 20px; overflow: visible; }
.fbtn .ic-k1, .fbtn .ic-k2 { transform-box: fill-box; transition: transform var(--fx-dur) var(--fx-spring); }
.fbtn:hover .ic-k1, .fbtn:focus-visible .ic-k1 { transform: translateX(-5px); }
.fbtn:hover .ic-k2, .fbtn:focus-visible .ic-k2 { transform: translateX(5px); }
.fbtn .fn { min-width: 20px; height: 20px; border-radius: 999px; background: var(--green); color: #fff; font-size: 12px; display: inline-grid; place-items: center; padding: 0 5px; }
.fbtn .fn:empty { display: none; }
.fbtn.soft { background: var(--fill); color: var(--ink); }
.fs-clear { min-height: 48px; border: 0; background: none; color: var(--ink-2); font: inherit; font-size: 14px; font-weight: 600; padding: 0 10px; cursor: pointer; }
.fs-clear[hidden] { display: none; }

.fsheet h3 { margin: 18px 0 6px; font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.fsheet .opt { display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 0 4px; cursor: pointer; border-radius: var(--r-sm); font-size: 16px; }
.fsheet .opt input { width: 22px; height: 22px; flex: none; accent-color: var(--green); }
.fsheet .opt .o-n { margin-left: auto; color: var(--ink-3); font-size: 13px; font-variant-numeric: tabular-nums; }
.fsheet .opt.is-zero { opacity: 0.38; }
.fsheet .brands { max-height: 280px; overflow-y: auto; overscroll-behavior: contain; margin: 0 -4px; padding: 0 4px; border-radius: var(--r-md); }
.fsheet .pr { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.fsheet .pr input { width: 100%; min-height: 48px; border: 0; border-radius: var(--r-md); background: var(--fill); color: var(--ink); padding: 0 14px; font: inherit; font-size: 16px; }
.fsheet .pr input:focus { outline: none; box-shadow: 0 0 0 1.5px var(--green); }
.fdock { position: sticky; bottom: calc(-24px - var(--safe-b)); margin: 22px -18px 0; padding: 12px 18px calc(14px + var(--safe-b)); display: flex; gap: 10px;
  background: linear-gradient(180deg, transparent, var(--card) 28%); z-index: 5; }
.fdock .fbtn { flex: 1; justify-content: center; }
.fdock .fbtn.soft { flex: 0 0 auto; }
.fdock .fbtn b { font-variant-numeric: tabular-nums; }

/* ---------- Respect people who ask for less motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; }
  .fx-settling { animation: none; transform: none; -webkit-text-fill-color: currentColor; background: none; }
  body.fx-deck main, body.fx-deck .topbar, body.fx-deck .side { scale: none; translate: none; }
  .feed.fx-in > .item, .dmenu { animation: none; }
  .sheet, .sheet-backdrop, .feed-wrap, .fx-bleed { transition-duration: 0.01ms; }
  .tab svg *, .fbtn svg * { transition: none; }
}
