/* ============================================================
   PHREE SKIN — shared chrome: announce · nav · footer · cart drawer
   (injected by app.js; styled here so every page matches)
   ============================================================ */

[data-logo] svg{ width:100%; height:100%; display:block; }

/* ---------- announce ---------- */
.announce{ background:var(--charcoal); color:#EAF2F6; position:relative; z-index:120; padding-block:.5rem; }
/* single-line rotating ticker — one message at a time, never wraps */
.announce__vp{ position:relative; height:1.5em; overflow:hidden; font-size:.76rem; letter-spacing:.02em; }
.announce__item{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  white-space:nowrap; padding-inline:1rem; text-align:center; pointer-events:none;
  opacity:0; transform:translateY(85%); transition:opacity .5s var(--e-out), transform .5s var(--e-out); }
.announce__item.is-on{ opacity:1; transform:none; pointer-events:auto; }
@media (max-width:520px){ .announce__vp{ font-size:.68rem; } }
@media (max-width:360px){ .announce__vp{ font-size:.62rem; } }

/* ---------- nav ---------- */
/* Always sticky + always visible. At rest it's flush + transparent; on scroll it
   detaches into a Seed-style FLOATING glass pill-bar (inset, rounded, blurred). */
.nav{ position:sticky; top:0; z-index:110; color:var(--ink);
  /* glass calibrated to Seed's captured values, translated to Phree's cool light palette:
     a translucent light fill (not a heavy white frost), strong frosted blur, no hard outline. */
  --nav-glass-bg:rgba(244,246,247,.55);   /* paper-3 tinted, translucent — light glass */
  --nav-glass-blur:34px;                   /* Seed captured 38px; 34 keeps text crisp on our light field */
  transition:padding .5s var(--e-out); }
.nav__row{ display:flex; align-items:center; justify-content:space-between; gap:1.25rem; padding-block:1.05rem;
  border:1px solid transparent; border-radius:var(--r-pill);
  transition:background .5s var(--e-out), backdrop-filter .5s, box-shadow .5s, border-color .5s, padding .45s var(--e-out); }

.nav.is-scrolled{ padding-top:.6rem; }               /* inset the floating bar from the very top */
/* Seed's glass technique (captured): the pill's fill IS a translucent blurred scrim, no hard
   outline — a strong ~32px blur + a mild inner highlight is what reads as real glass. Property
   crossfade is 0.3s ease-in-out (Seed's exact nav transition). Phree cool palette. */
.nav.is-scrolled .nav__row{
  padding-block:.55rem; padding-inline:1.15rem;
  background:var(--nav-glass-bg);
  backdrop-filter:blur(var(--nav-glass-blur)) saturate(1.4); -webkit-backdrop-filter:blur(var(--nav-glass-blur)) saturate(1.4);
  border-color:transparent;
  box-shadow:0 1px 0 rgba(255,255,255,.55) inset, 0 0 0 .5px rgba(255,255,255,.28) inset,
             0 20px 46px -28px rgba(20,40,55,.5), 0 2px 8px -5px rgba(20,40,55,.14); }
/* crossfade the glass in/out like Seed (bg + colour + blur, 0.3s ease-in-out) rather than the slow .5s slide */
.nav__row{ transition:background-color .3s ease-in-out, color .3s ease-in-out,
  backdrop-filter .3s ease-in-out, -webkit-backdrop-filter .3s ease-in-out, box-shadow .3s ease-in-out,
  border-color .3s ease-in-out, padding .45s var(--e-out); }
@media (min-width:681px){
  /* Float the glass pill inward WITHOUT overflowing right. The row is a .container (width:100%,
     margin-inline:auto). The old rule overrode margin to a fixed value on top of a width:100% box,
     so total width became 100vw + 2×margin → the pill (and the Buy button) spilled off the right.
     Instead we SHRINK the row by twice the inset and let the inherited auto side-margins re-centre
     it: margins land at (gutter − 1.15rem), and with the row's own 1.15rem padding the content sits
     back exactly on the page gutter — so nothing jumps and nothing overflows at any width. */
  .nav.is-scrolled .nav__row{ width:calc(100% - (var(--gutter) - 1.15rem) * 2); }
}
.brand{ display:inline-flex; align-items:center; gap:.65rem; color:inherit; }
.brand__mark{ width:34px; height:26px; color:inherit; flex:none; }
/* the wordmark's 7 Braille dots "write themselves in" on load — spelling the mark
   in Braille, one cell at a time (Seed-style wordmark animation, Phree's language). */
@keyframes brailleIn{ 0%{ opacity:0; transform:scale(.15) } 62%{ opacity:1; transform:scale(1.22) } 100%{ opacity:1; transform:scale(1) } }
.brand__mark svg circle{ transform-box:fill-box; transform-origin:center; opacity:0; animation:brailleIn .5s var(--e-back) both; }
.brand__mark svg circle:nth-of-type(1){ animation-delay:.12s }
.brand__mark svg circle:nth-of-type(2){ animation-delay:.19s }
.brand__mark svg circle:nth-of-type(3){ animation-delay:.26s }
.brand__mark svg circle:nth-of-type(4){ animation-delay:.33s }
.brand__mark svg circle:nth-of-type(5){ animation-delay:.40s }
.brand__mark svg circle:nth-of-type(6){ animation-delay:.47s }
.brand__mark svg circle:nth-of-type(7){ animation-delay:.54s }
/* a gentle re-spell on hover */
.brand:hover .brand__mark svg circle{ animation:brailleIn .5s var(--e-back) both; }
@media (prefers-reduced-motion:reduce){ .brand__mark svg circle{ animation:none; opacity:1 } }
.brand__word{ font-weight:var(--fw-med); font-size:.92rem; letter-spacing:.16em; display:flex; gap:.4em; }
.brand__word b{ font-weight:var(--fw-light); opacity:.55; }
.nav__links{ display:flex; gap:1.6rem; }
.nav__links a{ font-size:.85rem; letter-spacing:.01em; position:relative; padding-block:.3rem; color:inherit; opacity:.86; }
.nav__links a:hover{ opacity:1; }
.nav__links a::after{ content:""; position:absolute; left:0; bottom:0; width:100%; height:1px; background:var(--sky); transform:scaleX(0); transform-origin:right; transition:transform .4s var(--e-out); }
.nav__links a:hover::after{ transform:scaleX(1); transform-origin:left; }
.nav__actions{ display:flex; align-items:center; gap:.7rem; }
.nav__buy{ letter-spacing:.005em; white-space:nowrap; }  /* one button: "Купи Phree" until the cart has items, then "Кошница · N" */
.nav__buy .nav__cart-i{ width:15px; height:12px; margin-right:.15em; color:currentColor; }
.nav__buy-n{ display:inline-flex; align-items:center; justify-content:center; min-width:1.4em; height:1.4em;
  margin-left:.2em; padding:0 .35em; border-radius:var(--r-pill); background:var(--sky); color:#0b2531;
  font-size:.72em; font-weight:var(--fw-med); font-variant-numeric:tabular-nums; }
.nav__buy-n[hidden]{ display:none; }   /* class display must not override the hidden attr (empty cart = no badge) */
.lang{ display:flex; align-items:center; gap:.3rem; font-size:.74rem; opacity:.7; }
.lang button{ background:none; border:0; cursor:pointer; color:inherit; letter-spacing:.05em; padding:.15em; opacity:.6; }
.lang button.is-active{ opacity:1; font-weight:var(--fw-med); }
.nav__cart{ display:inline-flex; align-items:center; gap:.4em; background:none; border:0; cursor:pointer; color:inherit; font-size:.85rem; }
.nav__cart-i{ width:16px; height:13px; color:var(--sky); }
.nav__cart b{ color:var(--sky-deep); }
.burger{ display:none; flex-direction:column; gap:5px; background:none; border:0; cursor:pointer; padding:.4rem; color:inherit; }
.burger i{ width:22px; height:2px; background:currentColor; transition:transform .4s; }

/* dark-hero pages get a dark PAGE background so no white seam shows in the
   sub-pixel gap under the announce bar (the nav is transparent at rest). */
body.hero-dark, body.hero-media{ background:#0E1D29; }

/* nav white over a dark/media hero, until scrolled.
   `hero-media` = the home's full-screen VIDEO hero (white nav text at rest);
   `hero-dark`  = any solid dark hero. Both behave identically here. */
.hero-dark .nav:not(.is-scrolled),
.hero-media .nav:not(.is-scrolled){ color:#fff; }
.hero-dark .nav:not(.is-scrolled) .nav__cart b,
.hero-media .nav:not(.is-scrolled) .nav__cart b{ color:#fff; }
.hero-dark .nav:not(.is-scrolled) .nav__cart-i,
.hero-media .nav:not(.is-scrolled) .nav__cart-i{ color:#fff; }
.hero-dark .nav:not(.is-scrolled) .nav__quiz,
.hero-media .nav:not(.is-scrolled) .nav__quiz{ --b:transparent; --c:#fff; border-color:rgba(255,255,255,.4); }
.hero-dark .nav:not(.is-scrolled) .nav__quiz:hover,
.hero-media .nav:not(.is-scrolled) .nav__quiz:hover{ --b:transparent; border-color:#fff; }
/* the Buy button stays a solid pill on the media hero — flip it to white-on-charcoal so it never reads as a black hole */
.hero-dark .nav:not(.is-scrolled) .nav__buy,
.hero-media .nav:not(.is-scrolled) .nav__buy{ --b:#fff; --c:var(--charcoal); }
.hero-dark .nav:not(.is-scrolled) .nav__buy:hover,
.hero-media .nav:not(.is-scrolled) .nav__buy:hover{ --b:var(--sky-light); }

/* ---------- footer (dark charcoal bookend) ----------
   The sign-off is an ALIGNED slogan moment (Seed's footer wordmark logic in Phree's brand):
   the 7-dot Braille mark sits exactly ON the Braille dot-grid behind it — same lattice, same
   pitch — so the logo reads as dots surfacing out of the field, not a logo floated over noise.
   `--foot-gap` is the single source of truth for the grid pitch; the mark is sized so its own
   internal dot pitch renders at exactly that pitch, and app.js snaps it onto a grid node. */
.foot{ background:var(--charcoal); color:#D9E6EC; --foot-gap:44px; }
.foot__hero{ position:relative; overflow:hidden; text-align:center;
  padding-block:clamp(5rem,9vw,9rem);
  background:radial-gradient(90% 130% at 50% 120%, var(--charcoal-3), var(--charcoal) 60%); border-top:1px solid rgba(255,255,255,.06); }
.foot__dots{ position:absolute; inset:0; width:100%; height:100%; opacity:.85; }
.foot__heroin{ position:relative; z-index:2; display:flex; flex-direction:column; align-items:center;
  gap:clamp(1.6rem,3vw,2.4rem); }
/* the mark: sized so its 4×3 Braille lattice renders at exactly --foot-gap pitch (mark box =
   gap × 322/86.8 wide). Rendered pale so it sits on the grid as "brighter" grid dots, and app.js
   nudges it by the sub-pixel remainder so its centres land dead-on the grid nodes. */
/* The mark's `transform` carries the grid-SNAP offset and must apply INSTANTLY — never transition
   it, or getBoundingClientRect reads a mid-animation position and the snap chases its own tail.
   The reveal is done with a separate wrapper (opacity + rise), so the snap stays exact. */
.foot__mark{ width:calc(var(--foot-gap) * 3.703); height:auto;
  color:#fff; will-change:transform; }
.foot__mark svg{ display:block; width:100%; height:auto;
  opacity:.95; transform:translateY(14px);
  transition:opacity .9s var(--e-out), transform .9s var(--e-out); }
.foot__mark circle{ transition:opacity .4s var(--e-out); }
/* the mark rises + fades in — a deliberate, premium reveal — while its SNAP offset stays fixed */
.foot__hero:not(.is-in) .foot__mark svg{ opacity:0; transform:translateY(26px); }
.foot__hero.is-in .foot__mark svg{ opacity:.95; transform:none; }
.foot__big{ font-size:clamp(2.2rem,1.3rem + 4.4vw,4.6rem); color:#fff; }
.foot__form{ display:flex; gap:.6rem; flex-wrap:wrap; justify-content:center; width:100%; max-width:430px; }
.foot__form input{ flex:1; min-width:200px; padding:.95em 1.3em; border-radius:var(--r-pill); border:1px solid rgba(255,255,255,.18); background:rgba(255,255,255,.06); color:#fff; }
.foot__form input::placeholder{ color:rgba(255,255,255,.5); }
.foot__grid{ display:flex; justify-content:space-between; gap:2rem; flex-wrap:wrap; padding-block:3rem; border-top:1px solid rgba(255,255,255,.08); }
.foot__grid > div{ display:flex; flex-direction:column; gap:.65rem; }
.foot__k{ font-size:.7rem; text-transform:uppercase; letter-spacing:.16em; color:var(--sky-light); margin-bottom:.3rem; }
.foot__grid a, .foot__lang{ color:rgba(217,230,236,.72); font-size:.9rem; background:none; border:0; text-align:left; padding:0; cursor:pointer; transition:color .3s; }
.foot__grid a:hover, .foot__lang:hover{ color:#fff; }
.foot__legal{ display:flex; justify-content:space-between; gap:1.4rem; flex-wrap:wrap; padding-block:1.8rem; border-top:1px solid rgba(255,255,255,.08); font-size:.74rem; color:rgba(217,230,236,.55); }

/* ---------- cart drawer ---------- */
.cart{ position:fixed; inset:0; z-index:200; visibility:hidden; }
.cart.is-open{ visibility:visible; }
.cart__scrim{ position:absolute; inset:0; background:rgba(12,22,30,.42); opacity:0; transition:opacity .4s; }
.cart.is-open .cart__scrim{ opacity:1; }
.cart__panel{ position:absolute; top:0; right:0; height:100%; width:min(420px,92vw); background:var(--paper);
  display:flex; flex-direction:column; transform:translateX(100%); transition:transform .5s var(--e-out); box-shadow:-30px 0 60px -40px rgba(0,0,0,.5); }
.cart.is-open .cart__panel{ transform:none; }
.cart__head{ display:flex; align-items:center; justify-content:space-between; padding:1.3rem 1.4rem; border-bottom:1px solid var(--line); }
.cart__head h3{ font-size:1.1rem; }
.cart__x{ background:none; border:0; font-size:1.1rem; cursor:pointer; color:var(--muted); }
.cart__ship{ padding:.9rem 1.4rem 0; }
.cart__ship-t{ font-size:.8rem; color:var(--ink-2); margin-bottom:.5rem; }
.cart__ship-bar{ height:4px; border-radius:4px; background:var(--stone); overflow:hidden; }
.cart__ship-bar i{ display:block; height:100%; background:var(--sky); transition:width .5s var(--e-out); }
.cart__body{ flex:1; overflow-y:auto; padding:1.2rem 1.4rem; display:flex; flex-direction:column; gap:1.1rem; }
.cart__empty{ margin:auto; display:flex; flex-direction:column; align-items:center; gap:1rem; color:var(--muted); text-align:center; padding:2rem 0; }
.citem{ display:flex; gap:.9rem; }
.citem img{ width:72px; height:88px; object-fit:cover; border-radius:var(--r-sm); background:var(--paper-2); flex:none; }
.citem__main{ flex:1; display:flex; flex-direction:column; gap:.35rem; }
.citem__top{ display:flex; justify-content:space-between; gap:.5rem; }
.citem__top b{ font-weight:var(--fw-med); }
.citem__rm{ background:none; border:0; color:var(--muted); cursor:pointer; font-size:.85rem; }
.citem__sz{ font-size:.78rem; color:var(--muted); }
.citem__plan{ display:flex; gap:.4rem; margin-top:.15rem; }
.citem__plan button{ font-size:.72rem; padding:.3em .7em; border:1px solid var(--line-2); border-radius:var(--r-pill); background:var(--paper); cursor:pointer; color:var(--ink-2); }
.citem__plan button.on{ border-color:var(--sky); color:var(--sky-deep); background:var(--sky-soft); }
.citem__bot{ display:flex; align-items:center; justify-content:space-between; margin-top:.2rem; }
.qty{ display:inline-flex; align-items:center; border:1px solid var(--line-2); border-radius:var(--r-pill); }
.qty button{ width:28px; height:28px; background:none; border:0; cursor:pointer; color:var(--ink); }
.qty span{ min-width:22px; text-align:center; font-size:.85rem; }
.cart__foot{ padding:1.2rem 1.4rem calc(1.2rem + env(safe-area-inset-bottom)); border-top:1px solid var(--line); display:flex; flex-direction:column; gap:.9rem; }
.cart__row{ display:flex; justify-content:space-between; font-size:1rem; }
.cart__row .price{ font-size:1.1rem; }
.cart__note{ font-size:.72rem; color:var(--muted); text-align:center; }
body.cart-lock{ overflow:hidden; }

/* ---------- floating "Купи Phree" CTA (content pages, after the hero) ---------- */
.floatbuy{ position:fixed; right:clamp(1rem,3vw,2rem); bottom:clamp(1rem,3vw,2rem); z-index:105;
  display:inline-flex; align-items:center; gap:.55em; padding:.9em 1.4em; border-radius:var(--r-pill);
  background:var(--black); color:#fff; font-weight:var(--fw-med); font-size:.92rem; letter-spacing:.005em;
  box-shadow:0 18px 44px -20px rgba(10,10,10,.55), 0 2px 8px -4px rgba(20,40,55,.3);
  opacity:0; transform:translateY(18px) scale(.96); pointer-events:none;
  transition:opacity .5s var(--e-out), transform .5s var(--e-lift), background .35s; }
.floatbuy.is-in{ opacity:1; transform:none; pointer-events:auto; }
.floatbuy:hover{ background:#000; transform:translateY(-2px); }
.floatbuy__mark{ width:20px; height:16px; color:var(--sky); flex:none; }
@media (prefers-reduced-motion:reduce){ .floatbuy{ transition:opacity .3s; transform:none; } .floatbuy.is-in{ transform:none; } }

/* ---------- mobile ---------- */
/* the Buy button NEVER hides — only the secondary quiz link collapses out on narrow widths */
@media (max-width:860px){ .nav__links{ gap:1.3rem; } .nav__quiz{ display:none; } }
/* in-menu buy + lang are mobile-only (desktop uses the nav bar) */
.nav__menu-buy, .nav__menu-lang{ display:none; }
@media (max-width:680px){
  /* FULL-SCREEN mobile menu — fills the viewport; closes via the X (burger stays on top) */
  .nav__links{ position:fixed; inset:0; width:100%; height:100dvh; z-index:150;
    flex-direction:column; justify-content:center; align-items:center; gap:1.6rem;
    padding:5rem 2rem 2rem; background:var(--paper); color:var(--ink);
    opacity:0; visibility:hidden; transform:translateY(-6px);
    transition:opacity .35s var(--e-out), transform .35s var(--e-out), visibility .35s; }
  body.nav-open .nav__links{ opacity:1; visibility:visible; transform:none; }
  .nav__links a{ font-size:1.6rem; opacity:1; color:var(--ink); }
  .nav__links a::after{ display:none; }
  .nav__menu-buy{ display:inline-flex; margin-top:1rem; }
  .nav__links a.nav__menu-buy{ color:#fff; font-size:.98rem; }   /* keep the CTA white-on-black + button-sized */
  .nav__menu-lang{ display:flex; align-items:center; gap:.5rem; margin-top:.3rem; font-size:.95rem; }
  .nav__menu-lang button{ background:none; border:0; cursor:pointer; color:var(--muted); padding:.2em .3em; }
  .nav__menu-lang button.is-active{ color:var(--ink); font-weight:var(--fw-med); }
  .burger{ display:flex; position:relative; z-index:160; }   /* ABOVE the menu → always closable */
  body.nav-open .burger{ color:var(--ink); }                 /* dark X over the white menu */
  body.nav-open{ overflow:hidden; }
  .nav__actions{ gap:.6rem; }
  .nav__buy{ padding:.55em .95em; font-size:.8rem; }
  .nav .lang{ display:none; }
  /* cart drawer FULL-SCREEN on mobile (newsletter full-screen rules live after
     the .nl base block below, so source order doesn't override them) */
  .cart__panel{ width:100%; max-width:100%; box-shadow:none; }
  body.nav-open .burger i:first-child{ transform:translateY(3.5px) rotate(45deg); }
  body.nav-open .burger i:last-child{ transform:translateY(-3.5px) rotate(-45deg); }
  .foot__grid{ gap:1.6rem 2rem; }
  /* on mobile the in-nav Buy already covers it; keep the floating one out of the way */
  .floatbuy{ display:none; }
}


/* ================================================================
   NEWSLETTER MODAL — timed 25%-off welcome offer.
   Light-blue card, subtly-outlined field (stronger on focus), reveals
   the code directly on submit (no false "check your email").
   ================================================================ */
.nl{ position:fixed; inset:0; z-index:400; display:flex; align-items:center; justify-content:center;
  padding:1.2rem; opacity:0; visibility:hidden; transition:opacity .4s var(--e-out), visibility .4s; }
.nl.is-open{ opacity:1; visibility:visible; }
.nl__scrim{ position:absolute; inset:0; background:rgba(14,29,41,.42); backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px); }
.nl__card{ position:relative; width:min(430px,100%); text-align:center;
  background:var(--sky-soft);                       /* light blue, as requested */
  border-radius:var(--r-panel); padding:0; overflow:hidden;
  box-shadow:0 50px 100px -40px rgba(14,29,41,.5), 0 2px 10px -6px rgba(14,29,41,.3);
  transform:translateY(14px) scale(.985); transition:transform .5s var(--e-back); }
.nl.is-open .nl__card{ transform:none; }
.nl__x{ position:absolute; top:.85rem; right:.95rem; z-index:3; width:34px; height:34px; border:0; border-radius:50%;
  background:rgba(255,255,255,.85); color:var(--ink); font-size:1rem; line-height:1; cursor:pointer;
  display:flex; align-items:center; justify-content:center; box-shadow:0 2px 8px -3px rgba(14,29,41,.4);
  transition:background .25s, transform .25s; }
.nl__x:hover{ background:#fff; transform:scale(1.06); }
/* a real PRODUCT photo (non-transparent) heads the offer */
.nl__media{ position:relative; }
.nl__img{ width:100%; height:170px; object-fit:cover; object-position:center 52%; display:block; }
.nl__badge{ position:absolute; left:1rem; bottom:1rem; background:var(--black); color:#fff;
  padding:.4em .8em; border-radius:var(--r-pill); font-size:.78rem; font-weight:var(--fw-med); letter-spacing:.04em; }
.nl__body{ padding:1.7rem 2rem 2.1rem; }
.nl__mark{ display:inline-block; width:40px; color:var(--sky-deep); margin-bottom:.7rem; }
.nl__mark svg{ width:100%; height:auto; }
.nl__eyebrow{ font-size:var(--t-eyebrow); text-transform:uppercase; letter-spacing:.15em; font-weight:var(--fw-med); color:var(--sky-deep); margin-bottom:.5rem; }
.nl__title{ font-size:clamp(1.6rem,1.2rem+1.6vw,2.1rem); color:var(--ink); line-height:1.02; margin-bottom:.55rem; }
.nl__sub{ font-size:.98rem; color:var(--ink-2); max-width:30ch; margin:0 auto 1.3rem; }
.nl__form{ display:flex; flex-direction:column; gap:.7rem; }
.nl__form input{ width:100%; padding:1em 1.1em; border-radius:var(--r-pill);
  background:rgba(255,255,255,.55);                 /* sits on the light-blue field */
  border:1px solid rgba(14,29,41,.14);              /* subtle when idle */
  color:var(--ink); font-size:.98rem; transition:border-color .25s, background .25s, box-shadow .25s; }
.nl__form input::placeholder{ color:var(--muted); }
.nl__form input:focus{ outline:0; border-color:var(--sky-deep); background:#fff;
  box-shadow:0 0 0 3px rgba(78,150,180,.16); }     /* clear focus, still soft */
.nl__fine{ font-size:.74rem; color:var(--muted); margin-top:.9rem; }
/* revealed-code state */
.nl__done{ animation:nlIn .5s var(--e-out) both; }
@keyframes nlIn{ from{ opacity:0; transform:translateY(10px); } to{ opacity:1; transform:none; } }
.nl__check{ display:inline-flex; align-items:center; justify-content:center; width:46px; height:46px; margin-bottom:.6rem;
  border-radius:50%; background:var(--sky-deep); color:#fff; font-size:1.35rem; }
.nl__code{ display:inline-block; margin-top:.4rem; padding:.75em 1.4em; border:1px dashed var(--sky-deep);
  border-radius:var(--r-sm); background:rgba(255,255,255,.6); color:var(--ink);
  font-size:1.35rem; font-weight:var(--fw-med); letter-spacing:.14em; cursor:pointer;
  font-variant-numeric:tabular-nums; transition:background .25s, transform .25s; }
.nl__code:hover{ background:#fff; transform:translateY(-1px); }
.nl__copied{ font-size:.76rem; color:var(--sky-deep); margin-top:.6rem; font-weight:var(--fw-med); }
/* FULL-SCREEN on mobile — placed after the .nl base block so it isn't overridden by source order */
@media (max-width:680px){
  .nl{ padding:0; }
  .nl__card{ width:100%; height:100%; max-width:100%; border-radius:0; display:flex; flex-direction:column; }
  .nl__img{ height:34vh; }
  .nl__body{ flex:1; display:flex; flex-direction:column; justify-content:center; padding:1.5rem 1.6rem; }
}
@media (max-width:420px){ .nl__body{ padding:1.4rem; } }


/* ================================================================
   THE GIFT — brand slogan spelled in a dense Braille dot-field, below the
   footer. Generates left-to-right on scroll-in (engine in app.js).
   ================================================================ */
.foot__joinsub{ font-size:.92rem; color:rgba(217,230,236,.66); max-width:34ch; margin:-.15rem auto .1rem; }
.gift{ position:relative; overflow:hidden; background:#0a141b;
  min-height:clamp(220px,30vw,380px); }
.gift__bgvid{ position:absolute; inset:0; z-index:0; width:100%; height:100%; object-fit:cover;
  filter:brightness(.6) saturate(1.12); }
.gift__bgtint{ position:absolute; inset:0; z-index:1;
  background:radial-gradient(120% 130% at 50% 50%, rgba(9,20,28,.26), rgba(6,14,20,.58) 82%); }
.gift__dots{ position:absolute; inset:0; z-index:2; width:100%; height:100%; display:block; mix-blend-mode:screen; }
.gift__sr{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }
