/* ═══════════════════════════════════════════════════════════════════════
   Memoroam — Share Trip card  (prefix: shc-)

   A 9:16 artefact rendered from one trip and exported to 1080 × 1920 for
   Stories / Reels / TikTok. Opened from the trip detail sheet.

   Five sections, top to bottom:
     1 HEADER     flag + country, month beneath, ordinal pill right
     2 GLOBE      d3.geoOrthographic over world-atlas, real visited state
     3 POLAROIDS  three memory frames, tap to pick / change
     4 STATS      three values, hairline-separated
     5 FOOTER     memoroam wordmark, bottom right

   TYPE SYSTEM — three tiers, nothing else:
     DISPLAY  27px / 700 / -.02em   stat values
     TITLE    13px / 600 /  .14em   country name
     META      9px / 600 /  .18em   everything else
   Tracking is deliberately looser on META than TITLE: at 9px the same em
   value reads tighter, so .18 / .14 is what makes the two look equal.
   Vertical rhythm is a strict 8px unit — margins 8/16/24, gaps 8.

   THEMING — every colour on the card AND inside the globe resolves to a
   custom property below, so switching theme is a single class swap with
   no re-render. This is why the globe SVG is painted by CSS class rather
   than by d3 fill attributes: fill attributes cannot read var().
   ═══════════════════════════════════════════════════════════════════════ */

/* ── the screen: fullscreen sheet, same pattern as .mem-lightbox ── */
.shc-screen{
  /* left:50% with right:0 still set by inset:0 resolves the width to
     viewport-minus-50%, i.e. half the screen. Pin all four sides and centre
     with auto inline margins instead, which is unambiguous. */
  position:fixed;top:0;right:0;bottom:0;left:0;z-index:9600;background:var(--bg);
  width:min(100%,390px);margin-inline:auto;
  display:flex;flex-direction:column;
  padding-top:calc(env(safe-area-inset-top,0px) + 14px);
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .24s ease, visibility 0s linear .24s;
}
.shc-screen.open{opacity:1;visibility:visible;pointer-events:auto;transition-delay:0s;}

.shc-top{height:52px;flex-shrink:0;display:flex;align-items:center;gap:12px;padding:0 18px;}
.shc-back{
  width:34px;height:34px;border-radius:50%;flex-shrink:0;display:grid;place-items:center;
  background:rgba(0,0,0,.045);border:none;cursor:pointer;padding:0;
}
[data-theme="dark"] .shc-back{background:rgba(255,255,255,.07);}
.shc-back svg{width:16px;height:16px;stroke:var(--text);fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;}
.shc-top h2{font-family:'Playfair Display',serif;font-size:19px;font-weight:700;color:var(--text);}

/* first-run swipe hint. Own row above the card — floated in the gap
   between card and Share button it reads as jammed, the card renders at
   1:1 and leaves only ~10px there. Self-dismisses on first theme change;
   the row keeps its height so nothing reflows when it goes. */
.shc-hint{
  flex-shrink:0;height:24px;margin-top:14px;
  display:flex;align-items:center;justify-content:center;gap:9px;
  font-family:'IBM Plex Mono',monospace;font-size:8.5px;font-weight:600;
  letter-spacing:.18em;text-transform:uppercase;color:var(--muted);
  pointer-events:none;transition:opacity .45s ease;
}
.shc-hint svg{width:10px;height:10px;stroke:currentColor;fill:none;
  stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;opacity:.6;flex-shrink:0;}
.shc-hint.is-gone{opacity:0;}

/* The card is absolutely positioned inside this, NOT a flow child. Its
   618.7px layout height would otherwise stay in the flex flow even when
   scaled — transforms do not change layout — so on any screen where the
   stage is shorter than the card, the box overflowed into the actions row
   and buried the Share button. Out of flow it can never push anything. */
.shc-stage{flex:1;min-height:0;position:relative;overflow:hidden;}

/* ═══ THEMES ══════════════════════════════════════════════════════ */
.shc-card{
  --c-bg:#F0EBE3; --c-text:#1C1713; --c-muted:#8A7D72; --c-muted-strong:#6E6256;
  --c-line:rgba(0,0,0,.09);
  --c-accent:#C68A3A; --c-accent-bg:rgba(198,138,58,.10); --c-accent-br:rgba(198,138,58,.26);
  --c-frame:#ffffff; --c-route:#F04E23; --c-case:#ffffff;
  --g-ocean:#BFD9E5; --g-land:#E8E0CB; --g-visited:#3F8B6E;
  --g-border:#D6CCB5; --g-mesh:rgba(40,55,70,.08); --g-edge:rgba(74,140,138,.50);
}
.shc-card.t-sepia{
  --c-bg:#EDE2CE; --c-text:#2E2417; --c-muted:#8B7A5E; --c-muted-strong:#6B5A42;
  --c-line:rgba(70,50,20,.15);
  --c-accent:#9A6B2F; --c-accent-bg:rgba(154,107,47,.10); --c-accent-br:rgba(154,107,47,.28);
  --c-frame:#FBF6EC; --c-route:#B5432A; --c-case:#FBF6EC;
  --g-ocean:#D9CBAA; --g-land:#E9DFC4; --g-visited:#8A7A46;
  --g-border:#C9B98F; --g-mesh:rgba(90,70,35,.11); --g-edge:rgba(140,110,60,.5);
}
.shc-card.t-coast{
  --c-bg:#EAF0F2; --c-text:#14232B; --c-muted:#7A8D97; --c-muted-strong:#516670;
  --c-line:rgba(20,45,60,.12);
  --c-accent:#2E8B96; --c-accent-bg:rgba(46,139,150,.10); --c-accent-br:rgba(46,139,150,.28);
  --c-frame:#ffffff; --c-route:#E8503A; --c-case:#ffffff;
  --g-ocean:#A9D2E0; --g-land:#E4EAE4; --g-visited:#3E8C8C;
  --g-border:#C2D2D6; --g-mesh:rgba(20,50,65,.09); --g-edge:rgba(46,120,140,.45);
}
.shc-card.t-sunset{
  --c-bg:#F7E9E0; --c-text:#3A211B; --c-muted:#A2837A; --c-muted-strong:#7C5C52;
  --c-line:rgba(90,45,30,.14);
  --c-accent:#C4623C; --c-accent-bg:rgba(196,98,60,.10); --c-accent-br:rgba(196,98,60,.28);
  --c-frame:#FFF7F1; --c-route:#B8304C; --c-case:#FFF7F1;
  --g-ocean:#F0C3A8; --g-land:#F6E4D2; --g-visited:#B2705A;
  --g-border:#E0BCA4; --g-mesh:rgba(120,60,40,.10); --g-edge:rgba(180,100,70,.5);
}
.shc-card.t-midnight{
  --c-bg:#161311; --c-text:#EFE7DA; --c-muted:#877B6E; --c-muted-strong:#B3A796;
  --c-line:rgba(255,255,255,.11);
  --c-accent:#E8B871; --c-accent-bg:rgba(232,184,113,.12); --c-accent-br:rgba(232,184,113,.30);
  --c-frame:#F4EFE7; --c-route:#FF6A3D; --c-case:rgba(22,19,17,.60);
  --g-ocean:#1E2C36; --g-land:#3A3529; --g-visited:#4A9E7C;
  --g-border:#4A4436; --g-mesh:rgba(255,255,255,.07); --g-edge:rgba(120,190,185,.42);
}
.shc-card.t-dusk{
  --c-bg:#1B1A2B; --c-text:#EDE9F5; --c-muted:#847FA0; --c-muted-strong:#ABA5C2;
  --c-line:rgba(255,255,255,.11);
  --c-accent:#E4A9C8; --c-accent-bg:rgba(228,169,200,.12); --c-accent-br:rgba(228,169,200,.30);
  --c-frame:#F3F0F8; --c-route:#FF7A6B; --c-case:rgba(27,26,43,.55);
  --g-ocean:#252943; --g-land:#3C3A56; --g-visited:#5E8F86;
  --g-border:#4A4766; --g-mesh:rgba(255,255,255,.07); --g-edge:rgba(150,160,220,.38);
}
.shc-card.t-forest{
  --c-bg:#111A14; --c-text:#E4EDE3; --c-muted:#7C8F7F; --c-muted-strong:#A5B8A6;
  --c-line:rgba(255,255,255,.11);
  --c-accent:#C9A54E; --c-accent-bg:rgba(201,165,78,.12); --c-accent-br:rgba(201,165,78,.30);
  --c-frame:#EFF3ED; --c-route:#FF8A4C; --c-case:rgba(17,26,20,.60);
  --g-ocean:#16261F; --g-land:#2E3A2A; --g-visited:#4E8F5A;
  --g-border:#3D4A38; --g-mesh:rgba(255,255,255,.07); --g-edge:rgba(120,190,140,.38);
}
.shc-card.t-ink{
  --c-bg:#0F1622; --c-text:#E6EDF7; --c-muted:#75849B; --c-muted-strong:#9FAEC4;
  --c-line:rgba(255,255,255,.11);
  --c-accent:#6FB2D2; --c-accent-bg:rgba(111,178,210,.12); --c-accent-br:rgba(111,178,210,.30);
  --c-frame:#EEF3F9; --c-route:#FF5E5B; --c-case:rgba(15,22,34,.60);
  --g-ocean:#16233A; --g-land:#2B3345; --g-visited:#3F7E8C;
  --g-border:#3A4459; --g-mesh:rgba(255,255,255,.07); --g-edge:rgba(120,170,220,.40);
}

/* ═══ THE ARTEFACT ════════════════════════════════════════════════ */
.shc-card{
  overflow:hidden;
  width:348px;height:618.7px;                /* 9:16 → exports 1080 × 1920 */
  background:var(--c-bg);
  border-radius:20px;
  box-shadow:0 16px 44px rgba(0,0,0,.15),0 2px 8px rgba(0,0,0,.05);
  padding:22px;display:flex;flex-direction:column;
  transition:background-color .28s ease;
  /* The card's internal composition is authored against a fixed 348x618.7
     box — globe 240, frames 114, the pile's overlap arithmetic — so it is
     scaled to fit rather than reflowed. _shcFitCard() sets --shc-scale from
     the real stage size. Transform does not affect layout, so the actions
     row below is never pushed off-screen. */
  position:absolute;top:50%;left:50%;
  transform:translate(-50%,-50%) scale(var(--shc-scale,1));
  transform-origin:center center;
  /* plus glyph for empty polaroid slots, masked so it takes --c-muted */
  --plus:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M12 5v14M5 12h14'/%3E%3C/svg%3E");
  --lock:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2.5'/%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'/%3E%3C/svg%3E");
}
.shc-grain{position:absolute;inset:0;pointer-events:none;opacity:.5;}

/* theme-name flash, Instagram-filter pattern. Timing lives in JS (WAAPI)
   so a re-trigger can cancel the previous run mid-flight. The halo is the
   card's OWN background colour blurred behind the glyphs, which is what
   keeps it legible over the globe on all eight themes without a chip. */
.shc-flash{
  position:absolute;inset:0;z-index:8;display:grid;place-items:center;
  pointer-events:none;opacity:0;
}
.shc-flash span{
  font-family:'IBM Plex Mono',monospace;font-size:24px;font-weight:600;
  letter-spacing:.2em;text-transform:uppercase;color:var(--c-text);
  text-shadow:0 0 4px var(--c-bg),0 0 10px var(--c-bg),0 0 22px var(--c-bg),0 0 34px var(--c-bg);
  padding-left:.2em;
}

/* ═══ 1 · HEADER ══════════════════════════════════════════════════ */
.shc-rail{display:flex;align-items:center;justify-content:space-between;position:relative;z-index:2;}
.shc-when{display:flex;align-items:center;gap:8px;min-width:0;}
.shc-name{                                            /* TITLE */
  font-family:'IBM Plex Mono',monospace;font-size:13px;font-weight:600;
  letter-spacing:.14em;color:var(--c-text);line-height:1;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* public R2 flags/{iso2}.svg. Hairline border because flags with white
   fields (Japan, Poland) otherwise dissolve into the cream. */
.shc-flag{
  width:19px;height:auto;flex-shrink:0;display:block;border-radius:2px;
  border:1px solid var(--c-line);
}
.shc-num{                                             /* META + accent */
  font-family:'IBM Plex Mono',monospace;font-size:9px;font-weight:600;letter-spacing:.18em;
  padding:5px 10px;border-radius:100px;line-height:1;white-space:nowrap;flex-shrink:0;
  color:var(--c-accent);background:var(--c-accent-bg);border:1px solid var(--c-accent-br);
}
.shc-month{                                           /* META */
  margin-top:8px;position:relative;z-index:2;
  font-family:'IBM Plex Mono',monospace;font-size:9px;font-weight:600;
  letter-spacing:.18em;color:var(--c-muted);line-height:1;
}

/* distance strip: plane glyph + km. .plane-ico and .layover-label come
   from tickets.css; both need their colour re-pointed because the app's
   own tokens know nothing about the card's themes. */
.shc-dist{
  display:flex;align-items:center;justify-content:center;gap:8px;
  margin-top:16px;position:relative;z-index:2;
}
/* Heading is baked into the SVG path (transform="rotate(90 12 12)" in the
   markup), not applied here. A CSS rotate on the <svg> gets double-applied
   by html2canvas and exports the plane nose-down. */
.shc-dist .plane-ico{color:var(--c-muted);}
.shc-dist .layover-label{
  font-size:9px;font-weight:600;letter-spacing:.18em;color:var(--c-muted);opacity:1;
}

/* ═══ 2 · GLOBE ═══════════════════════════════════════════════════
   Fixed size, NOT flex:1. Flexing made the card's spare height pool as
   air centred around a capped globe, which put a white band between the
   km strip and the sphere. The slack lands in .shc-pile's auto margins
   instead, which also keeps the pile at a stable distance. */
.shc-globe{
  flex:0 0 auto;display:grid;place-items:center;
  margin-top:8px;position:relative;z-index:2;
}
.shc-globe svg{width:240px;height:240px;max-width:100%;display:block;}
.shc-globe .shc-err{
  font-family:'IBM Plex Mono',monospace;font-size:9px;letter-spacing:.14em;color:var(--c-muted);
}
/* Globe paint lives here, not on fill attributes, so a theme class swap
   restyles the sphere without re-projecting 177 country paths. */
.shc-globe .g-ocean     {fill:var(--g-ocean);}
.shc-globe .g-land      {fill:var(--g-land);   stroke:var(--g-border);stroke-width:.8;}
.shc-globe .g-visited   {fill:var(--g-visited);stroke:var(--g-border);stroke-width:.8;}
/* Booked but not yet flown. Derived from --g-visited by opacity rather than
   given its own token, so it stays correct across all eight themes without
   eight more declarations. */
.shc-globe .g-upcoming  {fill:var(--g-visited);opacity:.42;stroke:var(--g-border);stroke-width:.8;}
.shc-globe .g-mesh      {fill:none;stroke:var(--g-mesh);stroke-width:1;}
.shc-globe .g-edge      {fill:none;stroke:var(--g-edge);stroke-width:2.4;}
.shc-globe .g-case      {fill:none;stroke:var(--c-case);stroke-width:5.8;opacity:.92;}
.shc-globe .g-route     {fill:none;stroke:var(--c-route);stroke-width:3.2;}
.shc-globe .g-node-case {fill:var(--c-case);opacity:.92;}
.shc-globe .g-node      {fill:var(--c-route);}
.shc-globe .g-plane-case{fill:var(--c-case);stroke:var(--c-case);stroke-width:4.4;opacity:.92;}
.shc-globe .g-plane     {fill:var(--c-route);}
.shc-globe path,.shc-globe circle{transition:fill .28s ease, stroke .28s ease;}

/* ═══ 3 · POLAROIDS ═══════════════════════════════════════════════
   Frame matches .pmf-polaroid-frame (memories.css) — the app's canonical
   polaroid, which days-v2.css also mirrors. Production ratios at its
   180px width are padding 10/10/32, i.e. sides 5.5% and a chin of 17.8%.
   NOT even padding. Scaled here to a 114px frame: 6 / 6 / 20.

   Width is bounded by the card's 348px BORDER box (where overflow:hidden
   clips), not the 304px content box, so the pile may lean into the gutter:
     layout    3 x 114 - (2 x 17 overlap)  = 308
     rotation  129 tall x sin(4.5deg) x 2  = ~10
     total     318, leaving 15px clear each side.

   auto top AND bottom margins split the card's leftover height evenly
   above and below the pile rather than pooling it in one gap. */
.shc-pile{
  display:flex;justify-content:center;align-items:flex-start;
  margin:auto 0;position:relative;z-index:4;
}
.shc-pola{
  width:114px;flex-shrink:0;background:var(--c-frame);
  padding:6px 6px 20px;border-radius:2px;
  box-shadow:0 2px 6px rgba(0,0,0,.06), 0 12px 30px rgba(0,0,0,.14);
  position:relative;cursor:pointer;transition:filter .12s ease;
}
/* :active uses brightness, not the transform:scale(.96) the app uses on
   .pmf-batch-thumb — each frame already carries a rotation, and adding a
   scale would mean redeclaring all three rotations and keeping them in sync. */
.shc-pola:active{filter:brightness(.94);}
.shc-pola:nth-child(1){transform:rotate(-4.5deg);}
.shc-pola:nth-child(2){transform:rotate(1.5deg) translateY(-6px);margin:0 -17px;z-index:3;}
.shc-pola:nth-child(3){transform:rotate(3.5deg);}
.shc-photo{
  aspect-ratio:1;border-radius:1px;position:relative;overflow:hidden;
  background:#e8e0d4;                    /* .pmf-pol-photo placeholder tone */
}
.shc-photo img{width:100%;height:100%;object-fit:cover;display:block;}
/* .mem-lb-vignette, verbatim */
.shc-photo::after{
  content:'';position:absolute;inset:0;
  background:radial-gradient(ellipse at center,transparent 55%,rgba(0,0,0,.2) 100%);
}
/* empty slot — reads as waiting, not broken */
.shc-pola.is-empty .shc-photo{
  background:var(--c-bg);box-shadow:inset 0 0 0 1px var(--c-line);
  display:grid;place-items:center;
}
.shc-pola.is-empty .shc-photo::after{display:none;}
.shc-pola.is-empty .shc-photo::before{
  content:'';width:17px;height:17px;background:var(--c-muted);opacity:.5;
  -webkit-mask:var(--plus) center/contain no-repeat;
          mask:var(--plus) center/contain no-repeat;
}
/* Upcoming trip: memories are locked until departure, so an empty slot must
   not show a plus. Same rule the city sheet enforces with .cs-add-mem-locked. */
.shc-card.is-locked .shc-pola{cursor:default;}
.shc-card.is-locked .shc-pola.is-empty .shc-photo::before{
  width:19px;height:19px;opacity:.38;
  -webkit-mask:var(--lock) center/contain no-repeat;
          mask:var(--lock) center/contain no-repeat;
}

/* ═══ 4 · STATS ═══════════════════════════════════════════════════
   Three equal columns, centred, hairline-separated — the same treatment
   the ticket footer gives .footer-cell + .footer-cell. Centring matters
   because the values are short and uneven; left-aligned in equal columns
   they read as random gaps. */
.shc-stats{display:flex;align-items:stretch;position:relative;z-index:2;}
.shc-stat{
  flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:8px;text-align:center;
}
.shc-stat + .shc-stat{border-left:1px solid var(--c-line);}
/* The colour override is load-bearing: tickets.css ships
   .cell-value{color:var(--text)}, the APP's near-black. Without it the
   numbers stay black on every dark theme. Same for .cell-label. */
.shc-stat .cell-value{
  font-size:27px;font-weight:700;letter-spacing:-.02em;line-height:1;color:var(--c-text);
}
.shc-stat .cell-label{
  font-size:9px;font-weight:600;letter-spacing:.18em;
  color:var(--c-muted-strong);line-height:1;
}

/* ═══ 5 · FOOTER ══════════════════════════════════════════════════ */
.shc-foot{
  margin-top:24px;display:flex;align-items:center;justify-content:flex-end;
  position:relative;z-index:2;
}
.shc-mark{display:flex;align-items:center;gap:8px;}
.shc-mark img{width:16px;height:16px;border-radius:2px;display:block;}
.shc-mark span{
  font-family:'IBM Plex Mono',monospace;font-size:9px;font-weight:600;
  letter-spacing:.18em;color:var(--c-muted-strong);line-height:1;
}

/* ── action row: the app's primary button language ── */
.shc-actions{
  flex-shrink:0;display:flex;gap:10px;
  padding:16px 18px calc(env(safe-area-inset-bottom,0px) + 26px);
}
.shc-btn{
  flex:1;height:52px;border-radius:50px;border:none;cursor:pointer;
  display:flex;align-items:center;justify-content:center;gap:9px;
  font-family:'DM Sans',sans-serif;font-size:14.5px;font-weight:600;
  background:var(--text);color:var(--bg);
}
.shc-btn:disabled{opacity:.55;}
.shc-btn svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round;}

/* ── EXPORT STATE ──────────────────────────────────────────────────
   html2canvas captures whatever is on screen, so every editor-only
   affordance must be stripped first. Mirrors how pdesignExport adds
   .pdesign-exporting before capturing the passport page. */
.shc-card.is-exporting .shc-flash{display:none;}
.shc-card.is-exporting .shc-pola{cursor:default;}
/* an empty slot must never reach the exported image — a shared card with
   dashed placeholder squares in it reads as broken, not aspirational */
.shc-card.is-exporting .shc-pola.is-empty{display:none;}

/* ── share/save fallback overlay ───────────────────────────────────
   Programmatic blob downloads are silently ignored by many Android
   WebViews, and canShare can wrongly report false, so this long-press
   surface is the only reliable escape hatch. Same approach as
   _pdesignShowExportFallback. */
.shc-fallback{
  position:fixed;top:0;right:0;bottom:0;left:0;z-index:9700;background:rgba(12,9,7,.92);
  display:flex;align-items:center;justify-content:center;padding:24px;
  width:min(100%,390px);margin-inline:auto;
}
.shc-fb-card{display:flex;flex-direction:column;align-items:center;gap:14px;max-width:100%;}
.shc-fb-img{max-width:100%;max-height:62vh;border-radius:12px;display:block;
  box-shadow:0 20px 50px rgba(0,0,0,.5);}
.shc-fb-hint{font-family:'DM Sans',sans-serif;font-size:12.5px;color:rgba(255,255,255,.6);text-align:center;}
.shc-fb-dl{
  font-family:'DM Sans',sans-serif;font-size:14px;font-weight:600;
  color:#1C1713;background:#F0EBE3;padding:12px 30px;border-radius:50px;text-decoration:none;
}
.shc-fb-close{
  position:absolute;top:18px;right:18px;width:36px;height:36px;border-radius:50%;
  background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.18);
  color:#fff;font-size:20px;line-height:1;cursor:pointer;
}

/* ── memory picker ─────────────────────────────────────────────────
   Slide-up sheet listing this trip's photo-bearing memories. Sits above
   the share screen (9600) but below the fallback overlay (9700). */
.shc-picker{
  position:fixed;top:0;right:0;bottom:0;left:0;z-index:9650;background:rgba(12,9,7,.5);
  width:min(100%,390px);margin-inline:auto;
  display:flex;align-items:flex-end;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .22s ease, visibility 0s linear .22s;
}
.shc-picker.open{opacity:1;visibility:visible;pointer-events:auto;transition-delay:0s;}
.shc-pk-sheet{
  width:100%;background:var(--card);border-radius:20px 20px 0 0;
  padding:10px 18px calc(env(safe-area-inset-bottom,0px) + 22px);
  max-height:66vh;display:flex;flex-direction:column;
  transform:translateY(16px);transition:transform .26s cubic-bezier(.32,.72,0,1);
}
.shc-picker.open .shc-pk-sheet{transform:translateY(0);}
.shc-pk-handle{
  width:38px;height:4px;border-radius:2px;background:var(--border);
  margin:0 auto 14px;flex-shrink:0;
}
.shc-pk-title{
  font-family:'Playfair Display',serif;font-size:17px;font-weight:700;
  color:var(--text);margin-bottom:14px;flex-shrink:0;
}
.shc-pk-grid{
  display:grid;grid-template-columns:repeat(3,1fr);gap:8px;
  overflow-y:auto;-webkit-overflow-scrolling:touch;
}
.shc-pk-tile{
  aspect-ratio:1;border:none;padding:0;border-radius:8px;overflow:hidden;
  background:#e8e0d4;cursor:pointer;position:relative;
  transition:transform .15s;
}
.shc-pk-tile:active{transform:scale(.96);}
.shc-pk-tile img{width:100%;height:100%;object-fit:cover;display:block;}
/* already sitting in one of the three slots */
/* no memories on this trip yet — spans the grid rather than sitting in a cell */
.shc-pk-empty{
  grid-column:1 / -1;display:flex;flex-direction:column;align-items:center;
  gap:8px;padding:26px 12px 14px;text-align:center;
}
.shc-pk-empty svg{width:34px;height:34px;color:var(--muted);opacity:.4;margin-bottom:2px;}
.shc-pk-empty-title{
  font-family:'Playfair Display',serif;font-size:16px;font-weight:700;color:var(--text);
}
.shc-pk-empty-sub{
  font-family:'DM Sans',sans-serif;font-size:12.5px;color:var(--muted);max-width:240px;
}
.shc-lock-count{
  font-family:'DM Sans',sans-serif;font-size:12.5px;color:var(--muted);margin-top:2px;
}
.shc-lock-count b{
  font-family:'IBM Plex Mono',monospace;font-size:17px;font-weight:700;color:var(--text);
}
.shc-lock-sub{
  font-family:'DM Sans',sans-serif;font-size:11.5px;color:var(--muted);opacity:.8;
}
.shc-pk-empty-cta{
  margin-top:8px;padding:11px 26px;border-radius:50px;border:none;cursor:pointer;
  font-family:'DM Sans',sans-serif;font-size:13.5px;font-weight:600;
  background:var(--text);color:var(--bg);
}
.shc-pk-tile.is-used::after{
  content:'';position:absolute;inset:0;
  box-shadow:inset 0 0 0 2.5px var(--gold);border-radius:8px;
}

/* ── transient toast ── */
.shc-toast{
  position:fixed;left:50%;bottom:96px;transform:translate(-50%,12px);
  z-index:9800;padding:11px 20px;border-radius:50px;
  background:rgba(28,23,19,.94);color:#F0EBE3;
  font-family:'DM Sans',sans-serif;font-size:13px;
  opacity:0;pointer-events:none;transition:opacity .22s, transform .22s;
}
.shc-toast.is-in{opacity:1;transform:translate(-50%,0);}
