/* =============================================================================
   calculator.css — /calculator only.

   DESIGN LANGUAGE: matches neroscaling.com, which runs body[data-mood="daylight"]
   -- a beige page, not a dark one. Every value below was read off the live site
   on 2026-08-24 (computed styles + the daylight block in assets/css/styles.css),
   not eyeballed from a screenshot:

     page        #f8f3ec        panels   #ffffff / #fdf9f2
     text        #000000        accent   #006e6e on light, #008B8B on fills
     cards       1px rgba(0,0,0,0.08), radius 22px
     buttons     pill 999px, #008B8B, white, Agrandir Wide 500 15px,
                 shadow 0 12px 30px -12px rgba(0,139,139,0.6), hover darkens
     footer      #0a0a0a with white text -- the site keeps a dark footer
                 against the beige page, and so does this

   NOTE ON THE SPEC: NS-calculator-site.md section 7 asks for a black background
   and reserves cyan for the result number and the CTA only. That was written
   against an older, dark site. The live site is light and uses cyan for
   eyebrows, emphasis and controls throughout, so following the spec literally
   would make this page look like it belongs to a different company. Matching
   the site wins. Everything else in section 7 still holds: Agrandir Wide
   headings, Montserrat body, the result number is the largest type on the page
   by a wide margin, and it arrives on a 200ms fade and rise with no counting-up
   and no fake "calculating" delay.

   Round 6: this page now loads assets/css/styles.css, v2.css, v3.css and
   v5.css before this file, the same stack the homepage uses, so the header,
   the schedule section and the footer can be the homepage's own verbatim
   markup instead of a hand-copied approximation. This file keeps only what is
   genuinely calculator-only: the layout of the masthead, the sliders, the
   result panel, and its own colour/panel tokens (the site has no equivalent
   of this page's beige-panel-on-beige-page design, so those stay local
   rather than reusing homepage tokens that mean something different there).

   Mobile first, per spec section 1: owners open this from an email on a phone.

   Round 8: Vignesh asked for the page ground to be white at all times, not
   the beige (#f8f3ec) read off the live site above -- --bg is now #ffffff.
   The beige token stays alive only inside the booking card's left info panel
   (.bk-info's data-mesh="beige" grain, styled in v5.css, same as the
   homepage's booking section), which is unaffected by --bg. Nothing else on
   this page reads --bg for a beige effect: --panel/--panel-2 (the white
   result card and an unused warm-white tint) are untouched, and the slider
   thumb border / focus-ring "gap" shadows that reference var(--bg) already
   sat on the white .calc-section panel, not the page body, so swapping --bg
   to white only makes those rings match their real local background more
   exactly -- no behaviour or visible regression there.
   ========================================================================== */

@font-face {
  font-family: "Agrandir Wide";
  src: url("/assets/fonts/agrandir-wide.ttf") format("truetype");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
/* The homepage's second fallback face (assets/css/v3.css), so a heading that
   misses Agrandir Wide degrades the same way on both pages. */
@font-face {
  font-family: "Agrandir";
  src: url("/assets/fonts/agrandir-regular.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #ffffff;          /* page ground is white at all times (round 8) */
  --panel: #ffffff;       /* the result card, lifted off the page */
  --panel-2: #fdf9f2;     /* .ccs-card / .why on the live site */

  --text: #000000;
  --muted: rgba(0, 0, 0, 0.64);
  /* 0.60, not 0.45: at 0.45 the hint and capacity copy measured about 3.3:1
     on the beige page, under WCAG AA's 4.5:1 for body text. 0.60 clears it
     (about 4.6:1). The homepage resolves this token to solid black. */
  --muted-2: rgba(0, 0, 0, 0.60);

  --line: rgba(0, 0, 0, 0.10);
  --line-2: rgba(0, 0, 0, 0.18);

  --cyan: #008b8b;        /* fills: buttons, slider thumbs */
  /* Round 11 colour audit: only #FFFFFF/#000000/#F8F3EC/#008B8B may render,
     so --cyan-hi now aliases --cyan instead of the old #006e6e "type on
     light" shade. Fixes .field-label, .btn:hover, .result-label and
     .result-number in one place. */
  --cyan-hi: var(--cyan);
  --cyan-soft: rgba(0, 139, 139, 0.10);
  --cyan-line: rgba(0, 139, 139, 0.32);


  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 22px;

  /* Canon (brand-voice-visual-identity.md): Agrandir Wide for headings,
     Montserrat for body. This page now loads assets/css/styles.css, v2.css,
     v3.css and v5.css before this file (round 6), and v3.css's :root already
     sets --display/--body to that exact stack, so they are inherited from
     there rather than redeclared here. */

  /* The site's locked six-size type scale now lives in v5.css as --fs-1
     through --fs-6 (loaded before this file), responsive on its own at
     <=720px. These four roles just alias into it, so this file never needs
     its own mobile breakpoint for type. The single exception is
     .result-number, which keeps its own oversized display treatment (see
     --fs-result below) because spec section 7 requires it to be the largest
     type on the page by a wide margin. */
  --t-heading: var(--fs-1);
  --t-sub: var(--fs-2);
  --t-body: var(--fs-4);
  --t-label: var(--fs-6);

  /* .result-number's own token: no --fs-N is anywhere near this size, so it
     gets a dedicated variable rather than a bare literal, the same pattern
     v5.css uses for --fs-mark and --fs-logo. */
  --fs-result: clamp(84px, 27vw, 132px);
}

* { box-sizing: border-box; }

/* black behind the browser chrome: this page starts on a black strip and
   ends on a black footer (see v5.css round 14). Safari reads the colour
   from body, so body is black too (the html body rule outranks the plain
   body rule below); the strip, main, #schedule and the footer each paint
   their own background, so none of body's black shows inside the page. */
html { -webkit-text-size-adjust: 100%; }
html, html body { background: #000; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--body);
  font-size: var(--fs-4);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* As on the homepage (styles.css). The footer depends on it: its links carry
   no underline of their own except the one GivePower link that asks for it. */
a { color: inherit; text-decoration: none; }

/* ---------- Shell ---------- */
.wrap {
  max-width: 620px;
  margin: 0 auto;
  padding: 40px 20px 56px;
}

/* ---------- calc-section: bottom-radius handoff ----------
   Round 7. Whichever section sits last before the black .footer gets a
   white background, the homepage's bottom panel radius tucking into the
   footer (the footer's own negative margin-top pulls it up under whatever
   precedes it -- see assets/css/v5.css's .footer comment), position:relative
   and z-index:1 so it paints over the footer everywhere except at its own
   rounded corners, where the footer shows through.

   Before the first Calculate, #schedule is [hidden] and calc-section (this
   page's own full-bleed band, wrapping .wrap) is last, so it gets the
   treatment. calculator.js adds body.is-booking-open the moment #schedule
   is revealed; from then on the treatment moves onto #schedule instead, per
   the two rules below. .wrap's own padding (56px/64px bottom) already clears
   the 28px footer overlap, so no extra bottom padding is needed here; .bk's
   --v5-section-y (72px/120px) clears it by an even wider margin.

   Round 8: the page ground (--bg) is white at all times, not beige, so
   calc-section no longer needs to go transparent once body.is-booking-open
   -- it stays var(--v5-white) explicitly and only gives up its radius,
   z-index and position once #schedule.bk takes over the bottom-radius
   handoff below. There is nothing beige left to expose. */
main.calc-section {
  background: var(--panel);
  position: relative;
  z-index: 1;
  border-radius: 0 0 var(--v5-r-panel) var(--v5-r-panel);
}

body.is-booking-open main.calc-section {
  background: var(--v5-white);
  position: static;
  z-index: auto;
  border-radius: 0;
}

body.is-booking-open #schedule.bk {
  background: var(--v5-white);
  position: relative;
  z-index: 1;
  border-radius: 0 0 var(--v5-r-panel) var(--v5-r-panel);
}

/* Belt-and-braces: nothing on this page overrides `display` on section.bk,
   so the `hidden` attribute's UA-stylesheet rule already hides it, but spec
   asks this be explicit rather than incidental. */
#schedule[hidden] {
  display: none;
}

/* ---------- Masthead ---------- */
.masthead { text-align: center; }

/* ---------- Site header ----------
   Round 6: no longer duplicated here. This page now loads
   assets/css/styles.css, v2.css, v3.css and v5.css before this file (see
   index.html's <head>), the same stack the homepage uses, so
   .site-header/.pill/.pill-cta/.nds-hero-bar come from those shared files --
   there is nothing left to keep in step by hand for the pieces this page
   still uses. Collisions the shared cascade introduces on THIS page
   specifically are neutralised below.

   Round 7: this page's own header markup dropped the nav links, the menu
   CTA and the burger -- only the logo and .pill-cta remain, at every width
   (see index.html). The shared cascade still assumes a burger-driven mobile
   menu exists, so its ≤880px rule that hides .pill-cta and shows the burger
   in its place is overridden just below. */

/* Collision 1: v5.css's "header over silk" block assumes the un-scrolled
   header sits on the homepage's silk hero and switches the pill's top-state
   (data-compact="false") colours to dark-on-light. This page has no silk --
   the fixed header still sits on the plain black .nds-hero-bar strip
   (v2.css) -- so restore v2.css's original white-on-black top-state colours,
   scoped here only; the homepage itself is untouched. */
.pill[data-compact="false"] .pill-logo{color:var(--cyan);}
.pill[data-compact="false"] .pill-burger span{background:#fff;}

/* Collision 2 (round 7): styles.css's desktop .pill is a 3-column grid
   (logo / nav / right) because it expects a .pill-nav in the middle column.
   This page's header has only two children now (.pill-logo, .pill-right), so
   without help the auto-placement puts .pill-right into the middle (1fr)
   column instead of the trailing (auto) one -- the CTA would still end up
   flush with the right edge once the empty trailing column collapses to 0,
   but that depends on that column having nothing in it, which is fragile.
   Two explicit columns pinned to the ends is the same "logo left, CTA
   right, centre line" result without relying on that. align-items:center
   (inherited from styles.css's .pill) keeps both on the pill's centre line.
   Scoped to >880px: below that, styles.css switches .pill to flex with its
   own order/margin-left:auto layout (see Collision 3), which already does
   the right thing for two children without this rule's help. */
@media (min-width: 881px) {
  .pill { grid-template-columns: auto auto; justify-content: space-between; }
}

/* Collision 3 (round 7): styles.css hides .pill-cta and shows the burger at
   <=880px (its mobile menu takes over). This page has no burger and no menu
   to open, so the CTA has to stay put instead -- sized like the homepage's
   own mobile sticky CTA (assets/css/styles.css's .mobile-sticky-cta a,
   via .btn:not(.btn-sm) at <=600px) rather than its normal compact desktop
   size, since at this width it is the only way back to the calendar. */
@media (max-width: 880px) {
  .pill-cta {
    display: inline-flex;
    padding: 12px 20px;
    font-size: var(--fs-5);
  }
}

.title {
  font-family: var(--display);
  font-weight: 500;
  font-size: var(--t-heading);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--text);
  text-wrap: balance;
}

.subtitle {
  margin: 14px 0 0;
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--muted);
}

/* ---------- Inputs ---------- */
.inputs {
  margin-top: 38px;
  display: flex;
  flex-direction: column;
  gap: 26px;
}

.field { display: flex; flex-direction: column; }

.field-label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-family: var(--display);
  font-weight: 500;
  font-size: var(--t-label);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--cyan-hi);
  margin-bottom: 12px;
}

.field-value {
  font-family: var(--display);
  font-size: var(--t-body);
  letter-spacing: 0.02em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* --- slider ---
   Sized for a thumb, not a mouse pointer: a 28px handle inside a 44px tall hit
   area, which is the minimum comfortable touch target. */
.slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 44px;
  margin: -8px 0 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
}
.slider:focus-visible { outline: none; }

.slider::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.14);
}
.slider::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.14);
}

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 28px;
  height: 28px;
  margin-top: -12px;
  border-radius: 50%;
  background: var(--cyan);
  border: 3px solid var(--bg);
  box-shadow: 0 2px 10px -2px rgba(0, 139, 139, 0.7);
  transition: transform 140ms ease;
}
.slider::-moz-range-thumb {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--cyan);
  border: 3px solid var(--bg);
  box-shadow: 0 2px 10px -2px rgba(0, 139, 139, 0.7);
  transition: transform 140ms ease;
}
.slider:active::-webkit-slider-thumb { transform: scale(1.12); }
.slider:active::-moz-range-thumb { transform: scale(1.12); }
/* Same two-ring pattern as .btn:focus-visible: a 10% cyan halo was ~1.1:1
   against the beige page, below WCAG's 3:1 for a focus indicator. */
.slider:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px var(--bg), 0 0 0 5px var(--cyan); }
.slider:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px var(--bg), 0 0 0 5px var(--cyan); }

.field-hint {
  margin: 10px 0 0;
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--muted-2);
}

/* --- slider end labels ---
   The current value lives in .field-value beside the label; these two just
   anchor the ends of the scale so the range is legible without dragging. */
.field-scale {
  display: flex;
  font-family: var(--display);
  justify-content: space-between;
  margin-top: -2px;
  font-size: var(--t-label);
  letter-spacing: 0.04em;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---------- Two-column shell ----------
   Desktop: inputs left, output right. Mobile: one column, output below the
   button, which is the behaviour the page shipped with. */
.calc-grid { margin-top: 38px; }

.output-placeholder { display: none; }

/* ---------- Buttons ----------
   The site's pill, verbatim: 999px, #008B8B on white, Agrandir Wide 500, the
   cyan drop shadow. Round 11 colour audit: the hover no longer darkens to
   #006e6e -- --cyan-hi now aliases --cyan, so hover stays #008B8B.

   Collision 2: this page's header carries the homepage's own .pill-cta
   button (class="btn btn-sm pill-cta"), and this rule ties on specificity
   with the shared .btn-sm/.pill-cta rules (one class each) that size it --
   loaded later, it would win that tie on width, padding and font-size and
   blow the compact header CTA up to this panel's full-width size. .pill-cta
   is excluded so the header button is left entirely to the shared cascade
   (styles.css's .btn for colour/shape, v3.css/v5.css's .pill-cta for size,
   and this file's own ≤880px override above), exactly as on the homepage.
   .pill-menu-cta is excluded too though this page's header no longer has one
   (round 7 dropped it with the nav) -- harmless to keep and cheaper than
   re-litigating the selector if a menu CTA ever comes back. */
.btn:not(.pill-cta):not(.pill-menu-cta) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 16px 26px;
  background: var(--cyan);
  color: #ffffff;
  border: 1px solid var(--cyan);
  border-radius: 999px;
  font-family: var(--display);
  font-weight: 500;
  font-size: var(--fs-5);
  letter-spacing: 0.02em;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 0 12px 30px -12px rgba(0, 139, 139, 0.6);
  transition: background 200ms ease, border-color 200ms ease, transform 200ms ease;
}
.btn:hover {
  background: var(--cyan-hi);
  border-color: var(--cyan-hi);
  transform: translateY(-1px);
}
.btn:active { transform: translateY(0); }
.btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--bg), 0 0 0 6px var(--cyan);
}
.btn:disabled,
.btn[aria-disabled="true"] {
  background: rgba(0, 0, 0, 0.07);
  border-color: transparent;
  color: var(--muted-2);
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.btn-calc { margin-top: 4px; }

/* The homepage's phone pass (styles.css, <=600px): smaller full-size buttons,
   header button untouched. */
@media (max-width: 600px) {
  .btn:not(.btn-sm) { padding: 12px 20px; font-size: var(--fs-5); }
}

/* ---------- Result ----------
   Spec section 7: a short fade and rise, 200ms. No counting-up animation, no
   spinner, no fake delay. Instant maths reads as confident. */
.result {
  margin-top: 36px;
  padding: 32px 24px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: 0 18px 44px -28px rgba(0, 0, 0, 0.35);
  text-align: center;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 200ms ease, transform 200ms ease;
  /* clears the fixed header when calculator.js scrolls the result into view */
  scroll-margin-top: calc(var(--hdr-top) + 82px);
}
.result[hidden] { display: none; }
.result.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .result { transition: none; }
}

.result-label {
  font-family: var(--display);
  font-weight: 500;
  font-size: var(--t-label);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--cyan-hi);
  margin: 0;
}

/* The largest type on the page by a wide margin, per spec section 7. It should
   feel like the page handed them something. */
.result-number {
  font-family: var(--display);
  font-weight: 500;
  font-size: var(--fs-result);
  line-height: 0.92;
  letter-spacing: -0.04em;
  color: var(--cyan-hi);
  margin: 14px 0 0;
  font-variant-numeric: tabular-nums;
}

.result-unit {
  font-family: var(--display);
  font-weight: 500;
  font-size: var(--t-sub);
  letter-spacing: 0.02em;
  color: var(--text);
  margin: 6px 0 0;
}

.result-title {
  font-family: var(--display);
  font-weight: 500;
  font-size: var(--t-sub);
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--text);
  margin: 0;
  text-wrap: balance;
}

.result-body {
  margin: 20px 0 0;
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--muted);
  text-align: left;
}
.result-body + .result-body { margin-top: 14px; }

.result .btn { margin-top: 26px; }

/* ---------- Booking / Footer ----------
   Round 6: the hidden #booking section and its dynamically-mounted Calendly
   embed are gone. The schedule section is now the homepage's own
   section.bk#schedule, copied verbatim into index.html (static Calendly
   inline widget, beige mesh background), and the footer is the homepage's
   footer markup verbatim too. Both are fully styled by the shared
   assets/css/v5.css (.bk, .bk-card, .bk-info, .bk-cal, .footer, .fx, .fx-mark,
   etc.) that this page now loads, so there is nothing calculator-specific
   left to style for either -- see index.html's <head> and its schedule/
   footer markup. */

/* ---------- Desktop ----------
   Spec section 6 wants one screen. Two columns is how that survives four
   sliders plus a result panel: inputs left, output right, nothing below the
   fold until the booking section. */
@media (min-width: 880px) {
  .wrap { max-width: 1100px; padding: 56px 28px 64px; }

  .calc-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 52px;
    align-items: start;
    margin-top: 44px;
  }

  .inputs { margin-top: 0; gap: 30px; }
  .btn-calc { width: auto; justify-self: start; min-width: 240px; }

  .output { position: relative; }
  .result { margin-top: 0; padding: 40px 36px; }
  .result-body { text-align: center; }
  .result .btn { width: auto; min-width: 300px; }

  /* Without this the right column is an empty rectangle before the first
     calculation. Mobile has no empty column to fill, so it stays hidden there. */
  .output-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    min-height: 340px;
    padding: 40px 32px;
    border: 1px dashed var(--line-2);
    border-radius: var(--r-lg);
    text-align: center;
  }
  .output-placeholder[hidden] { display: none; }
  .output-placeholder-mark {
    width: 34px;
    height: 34px;
    color: var(--cyan);
    opacity: 0.5;
  }
  .output-placeholder-mark svg { width: 100%; height: 100%; }
  .output-placeholder p {
    margin: 0;
    max-width: 240px;
    font-size: var(--t-body);
    line-height: 1.6;
    color: var(--muted-2);
  }
}

/* Phones: the full "NERO SCALING" wordmark plus the CTA do not fit in one
   343px pill, so the logo stays in its collapsed "NS" chip state at every
   scroll position and the pill keeps logo and CTA on one centred row.
   Values mirror the shared compact-state rules (styles.css, v5.css). */
@media (max-width: 560px) {
  .site-header .pill { flex-wrap: nowrap; justify-content: space-between; align-items: center; row-gap: 0; }
  .pill .lm-rest,
  .pill[data-compact] .lm-rest { max-width: 0; opacity: 0; }
  .pill .lm-gap,
  .pill[data-compact] .lm-gap { width: 0; }
  .pill .pill-chip,
  .pill[data-compact] .pill-chip { opacity: 1; transform: scale(1); inset: auto; top: -.295em; bottom: -.09em; left: -.285em; right: -.2em; }
  .pill .pill-logo, .pill[data-compact] .pill-logo { margin-left: .285em; }
  /* Round 14: NS at the desktop logo size in both states, so it reads at the
     CTA's scale, and the same side padding in both so nothing shifts on
     scroll. On the black strip (not yet scrolled) the white chip is dropped:
     bare cyan NS. It returns with the glass pill. */
  .site-header .pill[data-compact] { padding: 0 16px; --fs-logo: 28px; }
  .site-header .pill[data-compact="false"] .pill-chip { opacity: 0; transform: scale(.9); }
}
