/* nm.css - snubblz.com design overlay, round 4
 *
 * Loaded ONLY when the request carries ?nm=1 (see meta.html.twig). Without it
 * this file is never fetched and the storefront is byte-for-byte unchanged.
 *
 * ---------------------------------------------------------------------------
 * WHY MINT IS BACK ON THE BUTTONS
 *
 * Round 3 moved calls to action onto Primary #B8ADDB, reasoning that the brand
 * book gives mint one job ("Streak/growth"). That was wrong, and the reason is
 * arithmetic rather than taste - hue distance from the #14111E ground:
 *
 *     Primary  #B8ADDB    1°     <- the same hue as the background, only lighter
 *     Accent   #9EE0C4   99°
 *
 * A button in Primary is the background wearing a highlight. The proof is in the
 * render, not in a statistic: with the CTA in Primary, the mint "Join waitlist"
 * button visibly out-shouted the purple "save your dock" button beside it - the
 * escape hatch was louder than the thing being sold.
 *
 * (A page-wide "% of coloured pixels that are violet" reading is NOT evidence
 * here: it was 86.6 % before this change and 84.1 % after, because the count is
 * dominated by the background field either way. It measures the ground, not the
 * design.)
 *
 * So the discipline stands and the job assignment changes. Mint is the LIVE
 * colour: the primary action, and the companion/journey - two expressions of
 * one idea. It comes off everything else (spec icons, eyebrows, step numbers,
 * checkmarks, the consent bar). Primary goes back to what the book actually
 * calls it: the brand's own colour - headings, highlights, structure.
 *
 *     Background #14111E · Surface #251E38 · Primary #B8ADDB
 *     Accent #9EE0C4 "streak/growth" · Body #D4D0E8 · Muted #9990B8
 *     Never use red.
 *
 * Type: serif by default (Fraunces + Figtree). ?nm=1&type=sans returns the
 * Poppins/Inter pairing. The book says typography is "not yet locked".
 * ---------------------------------------------------------------------------
 */

@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600&family=Figtree:wght@400;500;600;700&display=swap');

html.nm {
  --nm-bg:        #14111E;
  --nm-surface:   #251E38;
  --nm-primary:   #B8ADDB;
  --nm-accent:    #9EE0C4;
  --nm-body:      #D4D0E8;
  --nm-muted:     #9990B8;
  --nm-hi:        #FFFFFF;

  --nm-raised:    #1B1729;
  --nm-line:      #2E2740;
  --nm-line-soft: rgba(184,173,219,.12);
  --nm-accent-hi: #B4EBD5;
  --nm-ink:       #10202A;   /* dark ink that sits on mint without going muddy */

  --nm-r-md: 14px;
  --nm-r-pill: 999px;
}

/* =========================================================================
   1. THE ACCENT RULE
   Mint = the live thing: the primary action, and growth.  Primary = the brand:
   headings, highlights, structure.  Nothing else carries either.
   ========================================================================= */
html.nm .sn-cta-btn,
html.nm .sn-nav-cta,
html.nm .sn-h-cta,
html.nm a.sn-cta-btn.sn-magnet {
  background: var(--nm-accent) !important;
  background-image: none !important;
  color: var(--nm-ink) !important;
  border: 1px solid var(--nm-accent) !important;
  border-radius: var(--nm-r-pill) !important;
  /* crisp, not a haze: one tight shadow, no wide blur */
  box-shadow: 0 2px 10px -4px rgba(158,224,196,.45) !important;
  font-weight: 600 !important;
  letter-spacing: .005em !important;
  transition: background-color .16s ease, transform .16s ease;
}
html.nm .sn-cta-btn:hover,
html.nm .sn-h-cta:hover { background: var(--nm-accent-hi) !important; }
html.nm .sn-cta-btn:active { transform: translateY(1px); }
/* the nav CTA is repainted from JS (inline !important); a background transition
   there only masks the repaint and fights snubblz-nav-icons.js */
html.nm .sn-nav-cta { transition: transform .16s ease !important; }

html.nm .sn-cta-btn:focus-visible,
html.nm .sn-nav-cta:focus-visible,
html.nm a:focus-visible, html.nm button:focus-visible, html.nm input:focus-visible {
  outline: 2px solid var(--nm-accent) !important;
  outline-offset: 3px !important;
}

/* The H1's second line is a highlight, not an action and not growth. */
html.nm .sn-hero h1 span,
html.nm .sn-hero h1 em,
html.nm .sn-hero h1 strong { color: var(--nm-primary) !important; }

/* Mint keeps the journey and the companion - the same "live" idea as the CTA. */
html.nm .sn-journey .sn-j-name,
html.nm .sn-journey .sn-j-cn,
html.nm .sn-companions .sn-companion-available { color: var(--nm-accent) !important; }

/* ...and comes OFF everything that is neither. Spec icons are not growth, an
   eyebrow is not growth, a step number is not growth. */
html.nm .sn-section [class*="icon"] svg,
html.nm .sn-section svg[class*="icon"],
html.nm .nm-band-surface svg,
html.nm .sn-spec svg { color: var(--nm-primary) !important; stroke: var(--nm-primary) !important; opacity: .78; }
html.nm .sn-eyebrow,
html.nm [class*="eyebrow"],
html.nm [class*="kicker"] { color: var(--nm-muted) !important; letter-spacing: .16em !important; }
html.nm .sn-showcase strong { color: var(--nm-primary) !important; }

/* =========================================================================
   2. ONE CALL TO ACTION
   The waitlist stops competing. It was a filled mint button sitting beside the
   primary one - the escape hatch, louder than the thing being sold.
   ========================================================================= */
html.nm .sn-nav-waitlist-link,
html.nm .sn-nav-mobile-waitlist { display: none !important; }
html.nm .sn-hero button[type="submit"],
html.nm .sn-hero .sn-h-waitlist,
html.nm .sn-final-cta button[type="submit"] {
  background: transparent !important;
  background-image: none !important;
  color: var(--nm-body) !important;
  border: 1px solid var(--nm-line) !important;
  box-shadow: none !important;
  font-weight: 500 !important;
}
html.nm .sn-hero button[type="submit"]:hover,
html.nm .sn-final-cta button[type="submit"]:hover {
  border-color: var(--nm-primary) !important;
  color: var(--nm-hi) !important;
}
/* round 3 scaled the whole waitlist block with transform: scale(.94), which
   softens every glyph in it. Demote it with type and colour instead. */
html.nm .sn-hero form,
html.nm .sn-hero [class*="waitlist"] { transform: none !important; opacity: 1 !important; }
html.nm .sn-hero form input[type="email"],
html.nm .sn-final-cta form input[type="email"] {
  background: rgba(255,255,255,.03) !important;
  border: 1px solid var(--nm-line) !important;
  color: var(--nm-body) !important;
  border-radius: var(--nm-r-pill) !important;
}

/* =========================================================================
   3. RHYTHM, TONALLY - three shades of night, never cream
   ========================================================================= */
html.nm .nm-band-raised {
  background: var(--nm-raised) !important;
  box-shadow: 0 0 0 100vmax var(--nm-raised) !important;
  clip-path: inset(0 -100vmax) !important;
}
html.nm .nm-band-surface {
  background: var(--nm-surface) !important;
  box-shadow: 0 0 0 100vmax var(--nm-surface) !important;
  clip-path: inset(0 -100vmax) !important;
}
html.nm .nm-band-raised [class*="card"],
html.nm .nm-band-raised .sn-spec { background: var(--nm-bg) !important; border: 1px solid var(--nm-line) !important; }
html.nm .nm-band-surface [class*="card"],
html.nm .nm-band-surface .sn-spec,
html.nm .nm-band-surface .sn-faq-item { background: var(--nm-bg) !important; border: 1px solid var(--nm-line-soft) !important; }
html.nm .nm-band-surface .sn-faq-header { background: transparent !important; border: 0 !important; box-shadow: none !important; }

html.nm .sn-journey {
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(158,224,196,.06), rgba(0,0,0,0) 62%),
    var(--nm-bg) !important;
  padding-block: clamp(56px, 7vw, 104px) !important;
  border-block: 1px solid var(--nm-line);
}

/* Large soft radial gradients over a near-black ground band into visible rings
   at 8 bits. A faint noise layer dithers them away; pointer-events off so it
   cannot swallow a click. */
html.nm .sn-final-cta { position: relative; isolation: isolate; }
html.nm .sn-final-cta::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  opacity: .5; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.35'/%3E%3C/svg%3E");
}
html.nm .sn-final-cta > * { position: relative; z-index: 1; }

/* =========================================================================
   4. THE STATS STRIP - a card inside a card, and three things that are not
   the same kind of thing. Drop the outer box; let the three sit on the ground.
   ========================================================================= */
html.nm .sn-stats-strip {
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
}
html.nm .sn-stats-strip > * {
  background: transparent !important;
  border: 0 !important;
  border-left: 1px solid var(--nm-line) !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}
html.nm .sn-stats-strip > *:first-child { border-left: 0 !important; }

/* =========================================================================
   5. TYPE - serif by default; ?nm=1&type=sans returns Poppins/Inter
   ========================================================================= */
html.nm body, html.nm p, html.nm li, html.nm input, html.nm button,
html.nm a, html.nm span, html.nm div {
  font-family: Figtree, ui-sans-serif, system-ui, -apple-system, sans-serif;
}
html.nm h1, html.nm h2, html.nm h3, html.nm h4, html.nm h5, html.nm h6,
html.nm .sn-faq-q, html.nm .sn-stat-value, html.nm [class*="stat-num"] {
  font-family: Fraunces, Georgia, "Times New Roman", serif !important;
  font-weight: 500 !important;
  text-wrap: balance;
}
html.nm-sans body, html.nm-sans p, html.nm-sans li,
html.nm-sans a, html.nm-sans span, html.nm-sans div {
  font-family: Inter, ui-sans-serif, system-ui, sans-serif;
}
html.nm-sans h1, html.nm-sans h2, html.nm-sans h3,
html.nm-sans h4, html.nm-sans h5, html.nm-sans h6,
html.nm-sans .sn-faq-q { font-family: Poppins, Inter, sans-serif !important; font-weight: 700 !important; }

/* one scale, five steps - the live page measured 52 distinct steps above 13px */
html.nm h1 { font-size: clamp(2.4rem, 5vw, 3.7rem) !important; line-height: 1.06 !important; letter-spacing: -.02em !important; }
html.nm h2 { font-size: clamp(1.7rem, 3.2vw, 2.4rem) !important; line-height: 1.16 !important; letter-spacing: -.015em !important; }
html.nm h3 { font-size: 1.22rem !important; line-height: 1.34 !important; }
html.nm h4 { font-size: 1.04rem !important; line-height: 1.4 !important; font-weight: 600 !important; }
html.nm p  { line-height: 1.6; }
html.nm .sn-section > p, html.nm .sn-section-full > p { max-width: 62ch; margin-inline: auto; }

/* =========================================================================
   6. CONTRAST - the reassurance lines were the least legible on the page
   ========================================================================= */
html.nm .sn-final-cta p,
html.nm .sn-hero p,
html.nm [class*="shipping"], html.nm [class*="guarantee"],
html.nm [class*="refund"] { color: var(--nm-body) !important; }
html.nm .sn-price-old, html.nm del, html.nm s { color: var(--nm-muted) !important; opacity: 1 !important; }
html.nm .sn-faq-item p { color: var(--nm-muted) !important; }

/* =========================================================================
   7. SURFACES
   ========================================================================= */
html.nm [class*="card"], html.nm .sn-companion, html.nm .sn-spec { border-radius: var(--nm-r-md) !important; }
html.nm .sn-badge, html.nm [class*="pill"], html.nm [class*="chip"] { border-radius: var(--nm-r-pill) !important; }
html.nm .sn-companions-grid { grid-template-columns: minmax(0, 340px) !important; justify-content: center !important; }
html.nm .sn-sloth-gif-float { display: flex !important; }
html.nm header, html.nm .sn-header { background: rgba(20,17,30,.9) !important; backdrop-filter: blur(10px); }

@media (prefers-reduced-motion: reduce) {
  html.nm *, html.nm *::before, html.nm *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------- preview flag -- */
.nm-flag {
  position: fixed; inset: auto auto 16px 16px; z-index: 2147483000;
  background: var(--nm-surface); color: var(--nm-body);
  border: 1px solid var(--nm-line);
  font: 500 12px/1.5 Figtree, system-ui, sans-serif; letter-spacing: .03em;
  padding: 9px 14px; border-radius: var(--nm-r-pill);
  box-shadow: 0 8px 30px -10px rgba(0,0,0,.8);
}
.nm-flag a { color: var(--nm-accent); text-decoration: underline; margin-left: 10px; }

/* =========================================================================
   8. THE STATS STRIP, with the real class names
   Read off the DOM rather than guessed: the bordered box is .sn-stats-inner
   (not .sn-stats-strip), the three cards are .sn-stat-card, the value is a
   DIV.sn-stat-big - which is why the h-rules never reached it.
   ========================================================================= */
html.nm .sn-stats-inner {
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  padding-inline: 0 !important;
}
html.nm .sn-stat-card {
  background: transparent !important;
  border: 0 !important;
  border-left: 1px solid var(--nm-line) !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  /* the third card has no .sn-stat-src, so the citations sat at three
     different heights. Push them to a common baseline. */
  display: flex !important;
  flex-direction: column !important;
  padding-inline: 30px !important;
}
html.nm .sn-stats-grid > .sn-stat-card:first-child { border-left: 0 !important; }
html.nm .sn-stat-src { margin-top: auto !important; padding-top: 14px; }

html.nm .sn-stat-big {
  font-family: Fraunces, Georgia, serif !important;
  font-weight: 500 !important;
  font-size: 2rem !important;
  line-height: 1.1 !important;
  color: var(--nm-hi) !important;
  font-variant-numeric: tabular-nums;
}
html.nm-sans .sn-stat-big { font-family: Poppins, Inter, sans-serif !important; font-weight: 700 !important; }

/* an eyebrow is a label, not growth */
html.nm .sn-stats-label {
  color: var(--nm-muted) !important;
  letter-spacing: .16em !important;
  text-transform: uppercase;
  font-size: .72rem !important;
}
html.nm .sn-stats-foot { color: var(--nm-muted) !important; }
html.nm .sn-stat-body { color: var(--nm-body) !important; }
html.nm .sn-stat-src { color: var(--nm-muted) !important; font-size: .78rem !important; }

/* .nm-band-raised [class*="card"] is (0,2,0) and .sn-stat-card is (0,1,0), so
   the band rule was re-adding the border this section had just removed.
   Specificity, not order. */
html.nm .sn-stats-grid .sn-stat-card {
  background: transparent !important;
  border: 0 !important;
  border-left: 1px solid var(--nm-line) !important;
  border-radius: 0 !important;
}
html.nm .sn-stats-grid .sn-stat-card:first-child { border-left: 0 !important; }

/* the hero loop: matches the still it replaces exactly, so swapping between
   them (or falling back on autoplay refusal) shifts nothing */
html.nm .nm-hero-loop {
  display: block; width: 100%; height: auto;
  max-width: 100%; border-radius: 20px;
  background: var(--nm-bg);
}

/* =========================================================================
   9. THE ROOM FILM - click to play, below the fold
   The 12 s dolly earns its place here and not in the hero: nothing loads
   until the visitor asks for it, and a user-initiated video is allowed the
   controls that an autoplaying one must have anyway.
   ========================================================================= */
html.nm .nm-film {
  margin: 0 auto clamp(56px, 7vw, 96px);
  max-width: 940px;
  padding-inline: 24px;
}
html.nm .nm-film-btn {
  display: block; position: relative; width: 100%; padding: 0;
  border: 1px solid var(--nm-line); border-radius: var(--nm-r-md);
  background: var(--nm-bg); overflow: hidden; cursor: pointer;
  transition: border-color .18s ease, transform .18s ease;
}
html.nm .nm-film-btn:hover { border-color: var(--nm-accent); }
html.nm .nm-film-btn:active { transform: translateY(1px); }
html.nm .nm-film-poster { display: block; width: 100%; height: auto; }
/* off-centre deliberately: dead centre the button covers the OLED, which is
   the one thing in the poster worth looking at */
html.nm .nm-film-play {
  position: absolute; inset: auto auto 22px 22px; transform: none;
  width: 58px; height: 58px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--nm-accent); color: var(--nm-ink);
  box-shadow: 0 6px 26px -8px rgba(0,0,0,.75);
  transition: transform .18s ease;
}
html.nm .nm-film-btn:hover .nm-film-play { transform: scale(1.07); }
html.nm .nm-film-video {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--nm-line); border-radius: var(--nm-r-md);
  background: #000;
}
html.nm .nm-film figcaption {
  margin-top: 14px; text-align: center;
  color: var(--nm-muted); font-size: .92rem; letter-spacing: .01em;
}
@media (max-width: 780px) {
  html.nm .nm-film { padding-inline: 18px; }
  html.nm .nm-film-play { width: 52px; height: 52px; }
}

/* the hero visual, when nm.js has moved it up into the text block on a phone */
html.nm .sn-hero-visual[data-nm-hero-moved] {
  margin: 18px 0 22px;
  width: 100%;
}
html.nm .sn-hero-visual[data-nm-hero-moved] .nm-hero-loop,
html.nm .sn-hero-visual[data-nm-hero-moved] img { max-width: 100%; }

/* the two clips on the About page. Autoplaying, muted, looping, and each with
   a pause control because both run longer than five seconds. */
html.nm .nm-about-figure { margin: 26px 0 30px; position: relative; }
html.nm .nm-about-figure img,
html.nm .nm-about-figure video {
  display: block; width: 100%; height: auto;
  border-radius: var(--nm-r-md);
  border: 1px solid var(--nm-line);
  background: var(--nm-bg);
}
/* the editing clip is phone-shot portrait: give it a sane column rather than
   letting it run the full width of the text */
html.nm .nm-about-figure.nm-about-tall { max-width: 420px; margin-inline: auto; }

html.nm .nm-about-pause {
  position: absolute; inset: auto 10px 10px auto;
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(20,17,30,.72); color: var(--nm-body);
  border: 1px solid var(--nm-line);
  font: 500 12px/1 Figtree, system-ui, sans-serif;
  cursor: pointer; opacity: 0; transition: opacity .16s ease;
  backdrop-filter: blur(6px);
}
html.nm .nm-about-figure:hover .nm-about-pause,
html.nm .nm-about-pause:focus-visible { opacity: 1; }
@media (hover: none) { html.nm .nm-about-pause { opacity: 1; } }

/* the product page had its content flush against the nav: the header is 73 px
   and .container-main started at 74. Every other page type handles its own top
   spacing, so this is scoped to the product controller only. */
/* an inline theme rule zeroes padding on .container-main and friends with
   !important, so this has to match it rather than merely out-specify it. */
html.nm body.is-ctl-product .container-main { padding-top: clamp(28px, 4vw, 56px) !important; }

/* the dream world nodes: a real target, and a resting state that shows there is
   something to open */
html.nm .sn-journey .nm-j-hit { cursor: pointer; }
html.nm .sn-journey g.sn-j-stop { cursor: pointer; }

/* =========================================================================
   10. THE DREAM WORLDS, ALL SIX
   The constellation stays as the spine of the section; the row below simply
   shows every world. Five of them were behind a hover on an 8 px dot.
   ========================================================================= */
html.nm .sn-journey.nm-worlds-on svg.sn-j-svg { max-height: 300px; }

html.nm .nm-worlds {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  max-width: 1080px;
  margin: clamp(28px, 4vw, 52px) auto 0;
  padding-inline: 12px;
}
html.nm .nm-world {
  margin: 0;
  background: var(--nm-raised);
  border: 1px solid var(--nm-line);
  border-radius: var(--nm-r-md);
  overflow: hidden;
}
html.nm .nm-world img {
  display: block; width: 100%; aspect-ratio: 16 / 9;
  object-fit: cover; background: var(--nm-bg);
}
html.nm .nm-world figcaption { padding: 14px 16px 16px; }
html.nm .nm-world figcaption b {
  display: block;
  font-family: Fraunces, Georgia, serif; font-weight: 500;
  font-size: 1.02rem; color: var(--nm-hi); letter-spacing: -.01em;
}
html.nm-sans .nm-world figcaption b { font-family: Poppins, Inter, sans-serif; font-weight: 600; }
html.nm .nm-world figcaption span {
  display: block; margin-top: 4px;
  font-size: .87rem; color: var(--nm-muted);
}

/* "the nightstand" has no illustration and should not get a faked one: it is
   the real world the journey starts from, so it is drawn as the start marker. */
html.nm .nm-world-start {
  background:
    radial-gradient(120% 140% at 50% 0%, rgba(158,224,196,.10), rgba(0,0,0,0) 70%),
    var(--nm-raised);
  border-color: rgba(158,224,196,.28);
}
html.nm .nm-world-start .nm-world-here {
  display: block; aspect-ratio: 16 / 9; position: relative;
}
html.nm .nm-world-start .nm-world-here::before {
  content: ""; position: absolute; inset: 50% auto auto 50%;
  width: 11px; height: 11px; margin: -5.5px 0 0 -5.5px;
  border-radius: 50%; background: var(--nm-accent);
  box-shadow: 0 0 0 7px rgba(158,224,196,.16), 0 0 22px 3px rgba(158,224,196,.42);
}
html.nm .nm-world-start figcaption b { color: var(--nm-accent); }

@media (max-width: 900px) {
  html.nm .nm-worlds { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
}
@media (max-width: 560px) {
  html.nm .nm-worlds { grid-template-columns: 1fr; }
  html.nm .sn-journey.nm-worlds-on svg.sn-j-svg { max-height: 200px; }
}
