/* ==========================================================================
   Heaven Furniture Mart — base, type, buttons, shell
   Concept: hairlines, whitespace, weight contrast and one signal red.
   The page is PAPER by default; .section-dark is the exception.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--on-light);
  font-family: var(--sans);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, video, svg { max-width: 100%; height: auto; display: block; }

/* -deep, not --primary: a selection highlight sits under body copy, which
   needs 4.5:1, and #ED1C2E only reaches 4.37:1. */
::selection { background: var(--primary-deep); color: var(--primary-ink); }

/* ---- Type ---------------------------------------------------------------
   This INVERTS the previous system, which read: "real weight contrast, tight
   display tracking, uppercase reserved for eyebrows only" — headings at
   700-800 and letter-spacing -.02em.

   The new voice is the opposite on every axis: weight 200 instead of 800,
   POSITIVE tracking instead of negative, and uppercase promoted from
   exception to the rule for h1/h2/h3. Weight contrast still exists, it has
   just moved: it is now thin-display against bold-tiny-eyebrow, rather than
   bold-display against light-body. Deliberate reversal, not drift. ------- */

h1, h2, h3, h4 {
  font-family: var(--display);
  margin: 0 0 .5em;
  line-height: 1.02;
  text-transform: uppercase;
  text-wrap: balance;
}
/* Tracking scales inversely with size: the smaller the caps, the more air
   they need to stay countable as separate letters. */
h1 { font-size: var(--fs-h1); font-weight: 200; letter-spacing: .045em; }
h2 { font-size: var(--fs-h2); font-weight: 200; letter-spacing: .045em; }
h3 { font-size: var(--fs-h3); font-weight: 300; letter-spacing: .06em; line-height: 1.12; }
h4 { font-size: 1rem;         font-weight: 600; letter-spacing: .08em; line-height: 1.3; }

p { margin: 0 0 1.1em; max-width: var(--maxw-text); }
p:last-child { margin-bottom: 0; }

.lead {
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--on-light-mute);
  max-width: 56ch;
}

/* The counterweight to the thin display type: small, heavy, wide, dark. */
.eyebrow {
  font-family: var(--sans);
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--on-light);
  margin: 0 0 1rem;
  display: block;
}
/* -deep, not --brass/--primary: 13px is body-copy size and needs 4.5:1. */
.eyebrow--brass { color: var(--primary-deep); }
/* Eyebrow with the reference's short leading rule. */
.eyebrow--rule { display: flex; align-items: center; gap: .7rem; }
.eyebrow--rule::before {
  content: ""; flex: none; width: 26px; height: 2px; background: var(--primary);
}

a { color: inherit; }

/* Tabular figures for anything numeric — dimensions ARE content. */
.spec, .tabular, table { font-variant-numeric: tabular-nums; }

/* Giant low-contrast background type. Decorative by definition — 1.21:1 on
   paper — so it must never be the only carrier of a word that matters. */
.ghost-type {
  font-family: var(--display);
  font-weight: 200;
  font-size: var(--fs-ghost);
  line-height: .78;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--ghost);
  user-select: none;
  pointer-events: none;
}

/* ---- Layout ------------------------------------------------------------- */
.wrap { width: min(100% - 2.5rem, var(--maxw)); margin-inline: auto; }
.wrap--narrow { width: min(100% - 2.5rem, 860px); margin-inline: auto; }

section { padding-block: var(--section); }

/* ---- Surface bands -----------------------------------------------------
   .section-dark is the new exception (hero, meta strip, corridor, red band
   opt out separately). Everything inside it flips to the on-dark roles.

   .section-light predates the flip and appears in 15 places across 13 pages.
   It used to mean "the light one in a dark site"; it now means "the quieter
   paper band", so those pages keep working and gain a subtle alternation
   instead of a jarring inversion. -------------------------------------- */
.section-light { background: var(--paper-2); color: var(--on-light); }

.section-dark { background: var(--ink); color: var(--on-dark); }
.section-dark .lead { color: var(--on-dark-mute); }
.section-dark .eyebrow { color: var(--on-dark); }
.section-dark .eyebrow--brass { color: var(--primary-lite); }  /* 5.04:1 on ink.
                                                             --primary is 4.33:1
                                                             here, and 13px/700 is
                                                             NOT WCAG large text
                                                             (that needs 18.66px
                                                             bold), so this owes
                                                             the full 4.5:1 */
.section-dark .hairline { background: rgba(255, 255, 255, .14); }
.section-dark h1, .section-dark h2, .section-dark h3 { color: var(--on-dark); }

.stack > * + * { margin-top: var(--gap); }

.grid { display: grid; gap: var(--gap); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }

/* Skip link — accessibility. The fill is now dark red, so the label is
   white; the old skin's lime took dark text. */
.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--ar-signal); color: var(--primary-ink);
  padding: 12px 20px; font-weight: 700; z-index: 100;
}
.skip:focus { left: 0; }

/* Visible focus everywhere. #D41929 is 5.29:1 on paper and 3.53:1 on --ink,
   so one outline colour clears the 3:1 non-text bar on both surfaces. */
:focus-visible {
  outline: 3px solid var(--ar-signal);
  outline-offset: 3px;
}

/* ==========================================================================
   BUTTONS
   ========================================================================== */

/* ---- Primary: the "Tenon" ----------------------------------------------
   A hard-edged face sitting on a solid offset shadow block. On hover the face
   slides INTO its shadow and the shadow vanishes: the joint seats, like a
   tenon dropping into a mortise. No gradient, no blur, no glow.

   In the new palette the face is red and the block is blue-black, which is
   the reference's own pairing. The old skin used --primary-deep for the
   block; that is now the face colour, so the block moved to --ink. -------- */
.btn {
  --btn-bg: var(--primary-deep);   /* -deep: the label is 17px/700, under
                                      WCAG's 18.66px bold large-text cutoff,
                                      so it needs 4.5:1. White on #ED1C2E is
                                      4.37:1 and fails; on #D41929, 5.29:1. */
  --btn-fg: var(--primary-ink);
  --btn-shadow: var(--ink);
  --btn-fill: var(--ink);          /* hover wash: red face → blue-black    */
  --btn-fill-fg: var(--on-dark);   /* ...and the label that goes with it   */
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  min-height: 52px;
  padding: 14px 28px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 0;
  border-radius: 0;                /* hard edges — structure, not softness */
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: .01em;
  text-decoration: none;
  text-transform: none;            /* sentence case */
  cursor: pointer;
  --mag-x: 0px;   /* magnetic lean toward the cursor (js/magnetic.js) */
  --mag-y: 0px;
  box-shadow: var(--lift) var(--lift) 0 0 var(--btn-shadow);
  transform: translate(calc(0px + var(--mag-x)), calc(0px + var(--mag-y)));
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              background var(--dur) var(--ease), color var(--dur) var(--ease);
}

/* Interactive fill: on hover the button's own background crossfades to the
   wash colour (--btn-fill). Deliberately a background swap, NOT a pseudo-
   element — many .btn labels are raw text nodes, which a positioned
   ::before paints straight over (the hover missing-label bug).

   --btn-fill-fg exists because the wash can invert the surface's lightness.
   Swapping the background without the label colour is how a variant ends up
   with white-on-white on hover. */
.btn:hover,
.btn:focus-visible {
  transform: translate(calc(var(--lift) + var(--mag-x)), calc(var(--lift) + var(--mag-y)));
  box-shadow: 0 0 0 0 var(--btn-shadow);
  background: var(--btn-fill, var(--ink));
  color: var(--btn-fill-fg, var(--btn-fg));
}
.btn:active {
  transform: translate(calc(var(--lift) + 1px + var(--mag-x)), calc(var(--lift) + 1px + var(--mag-y)));
}

/* White face on a blue-black block — the inverse Tenon. */
.btn--bone {
  --btn-bg: var(--paper); --btn-fg: var(--on-light);
  --btn-shadow: var(--ink);
  --btn-fill: var(--ink); --btn-fill-fg: var(--on-dark);
}
/* On a dark band a white button needs a visible block: red, not ink. */
.section-dark .btn--bone { --btn-shadow: var(--primary-deep); }

/* Ghost: no fill, a 2px rule. Default is now the LIGHT case (the page is
   paper); .section-dark carries the inversion. The old file had this
   backwards, with .section-light patching a dark default. */
.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--on-light);
  --btn-shadow: transparent;
  --btn-fill: var(--ink); --btn-fill-fg: var(--on-dark);
  box-shadow: inset 0 0 0 2px var(--on-light);
}
.btn--ghost:hover, .btn--ghost:focus-visible {
  transform: none;                 /* no block to seat into */
  background: var(--ink);
  color: var(--on-dark);
  box-shadow: inset 0 0 0 2px var(--ink);
}
.section-dark .btn--ghost {
  --btn-fg: var(--on-dark);
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .5);
}
.section-dark .btn--ghost:hover,
.section-dark .btn--ghost:focus-visible {
  background: var(--paper);
  color: var(--on-light);
  box-shadow: inset 0 0 0 2px var(--paper);
}

.btn--sm { min-height: 48px; padding: 11px 20px; font-size: var(--fs-small); --lift: 4px; }

/* Reduced motion: swap the physical slide for a colour-only state change.
   The magnetic lean and the interactive fill are pointer flourishes — off. */
@media (prefers-reduced-motion: reduce) {
  .btn { --mag-x: 0px !important; --mag-y: 0px !important; }
  .btn:hover, .btn:focus-visible {
    transform: none;
    box-shadow: var(--lift) var(--lift) 0 0 var(--btn-shadow);
    background: var(--btn-fill);
    color: var(--btn-fill-fg, var(--btn-fg));
  }
}

/* ---- Secondary: the "Rule" link ---------------------------------------
   No box. A 2px baseline rule inset from both ends that draws out to full
   width on hover, and goes red as it lands. --hair would be 1.44:1 here —
   correct for a divider, far too faint for the only affordance on a link. */
.rule-link {
  position: relative;
  display: inline-block;
  padding: 6px 0 10px;
  font-weight: 600;
  text-decoration: none;
  color: inherit;
  min-height: 44px;
}
.rule-link::after {
  content: "";
  position: absolute;
  left: 12%; right: 12%; bottom: 4px;
  height: 2px;
  background: var(--on-light);
  transition: left var(--dur) var(--ease), right var(--dur) var(--ease),
              background var(--dur) var(--ease);
}
.rule-link:hover::after,
.rule-link:focus-visible::after { left: 0; right: 0; background: var(--primary); }
.section-dark .rule-link::after { background: rgba(255, 255, 255, .55); }
.section-dark .rule-link:hover::after { background: var(--primary); }

/* ==========================================================================
   THE AR BUTTON — still the loudest element on the site, but the volume now
   comes from form rather than hue. The old skin reserved lime #C6F24E for AR
   and nothing else; with AR folded into the signal red, the viewfinder
   brackets do that work: bright red silhouette, deep red fill, and the only
   continuous animation anywhere on the site.
   ========================================================================== */
.btn-ar {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .65rem;
  min-height: 56px;
  padding: 15px 30px;
  background: var(--ar-signal);
  color: var(--primary-ink);       /* was --ink: the fill is dark red now  */
  border: 0;
  border-radius: 0;
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: .01em;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
/* Hover DARKENS. Brightening to #ED1C2E would drop the white label to
   4.37:1 — a hover state has to pass too. */
.btn-ar:hover, .btn-ar:focus-visible { background: var(--ar-signal-dp); }
.btn-ar:active { transform: scale(.985); }

/* Four viewfinder brackets. */
.btn-ar::before, .btn-ar::after,
.btn-ar > .br-b::before, .btn-ar > .br-b::after {
  content: "";
  position: absolute;
  width: 13px; height: 13px;
  border: 2.5px solid var(--ar-bracket);
  animation: br-breathe 3.5s var(--ease) infinite;
}
.btn-ar::before { top: -6px; left: -6px; border-right: 0; border-bottom: 0; }
.btn-ar::after  { top: -6px; right: -6px; border-left: 0; border-bottom: 0; }
.btn-ar > .br-b::before { bottom: -6px; left: -6px; border-right: 0; border-top: 0; }
.btn-ar > .br-b::after  { bottom: -6px; right: -6px; border-left: 0; border-top: 0; }
.btn-ar > .br-b { position: absolute; inset: 0; pointer-events: none; }

@keyframes br-breathe {
  0%, 100% { opacity: .45; transform: translate(0, 0); }
  50%      { opacity: 1;   transform: translate(-2px, -2px); }
}
.btn-ar::after,
.btn-ar > .br-b::before { animation-delay: .1s; }
.btn-ar > .br-b::after  { animation-delay: .2s; }

.btn-ar svg { width: 20px; height: 20px; flex: none; }

.btn-ar--block { width: 100%; }

/* ==========================================================================
   MOBILE BOTTOM DOCK
   The site's only header is .pill-head (css/nav.css, built by js/chrome.js);
   the .site-head / .menu / .menu-btn / .nav block that used to live here was
   removed in the re-skin after grep confirmed zero call sites in any of the
   33 HTML files or any module — it had been unreachable dead code.
   ========================================================================== */
.dock {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-dock);
  display: none;
  background: rgba(17, 18, 25, .96);
  border-top: var(--edge);
  padding-bottom: env(safe-area-inset-bottom);
}
.dock-inner { display: grid; grid-template-columns: 1fr 1.3fr 1fr; }
.dock a {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; min-height: 60px; padding: 8px 4px;
  font-size: .75rem; font-weight: 600; text-decoration: none;
  color: var(--on-dark-mute);
}
.dock a svg { width: 20px; height: 20px; }
.dock a.is-ar { background: var(--ar-signal); color: var(--primary-ink); font-weight: 800; }
@media (max-width: 767px) {
  .dock { display: block; }
  body { padding-bottom: 64px; }
}

/* ==========================================================================
   FOOTER — one of the four surfaces that stays dark.
   ========================================================================== */
.site-foot {
  background: var(--ink-2);
  color: var(--on-dark);
  border-top: 0;
  padding-block: clamp(2.5rem, 6vw, 4.5rem) 2rem;
}
.foot-grid {
  display: grid; gap: 2.5rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
}
.foot-grid h4 { color: var(--on-dark); margin-bottom: .8rem; }
.foot-grid ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.foot-grid a {
  color: var(--on-dark-mute); text-decoration: none; font-size: var(--fs-small);
  transition: color var(--dur) var(--ease);
}
.foot-grid a:hover { color: var(--on-dark); }
.foot-base {
  margin-top: 2.5rem; padding-top: 1.5rem; border-top: var(--edge);
  display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between;
  color: var(--on-dark-mute); font-size: .8125rem;
}
/* The reference's pipe bar under the footer: one row of the collections on a
   half-step-lighter ground. Full-bleed, so it sits outside .wrap and eats the
   footer's bottom padding. Without :has you just get 2rem more --ink-2 below
   it — visually inert, not a break. */
.site-foot:has(.foot-rail) { padding-bottom: 0; }
.foot-rail {
  background: var(--ink-3);
  margin-top: 2.5rem;
  padding-block: .9rem;
}
.foot-rail ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .45rem 1.1rem;
}
.foot-rail a {
  color: var(--on-dark-mute); text-decoration: none;
  font-size: .75rem; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  transition: color var(--dur) var(--ease);
}
.foot-rail a:hover { color: var(--on-dark); }
.foot-rail li + li::before {
  content: "|"; margin-right: 1.1rem;
  color: rgba(255, 255, 255, .22);
}

/* ==========================================================================
   BREADCRUMBS — now on paper.
   ========================================================================== */
.crumbs {
  padding-top: 1.5rem;
  font-size: var(--fs-small);
  color: var(--on-light-mute);
}
.crumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: .4rem; margin: 0; padding: 0; }
.crumbs a { text-decoration: none; color: var(--on-light); font-weight: 600; }
.crumbs a:hover { color: var(--primary-deep); }
.crumbs li + li::before { content: "›"; margin-right: .4rem; color: var(--hair-strong); }

/* ==========================================================================
   SCROLL REVEAL — opt-in, and it fails OPEN.
   Content is visible by default; JS adds .reveal-on to enable the effect, so
   a dead script can never leave the page blank.
   ========================================================================== */
.reveal-on .reveal { opacity: 0; transform: translateY(18px); }
.reveal-on .reveal.in {
  opacity: 1; transform: none;
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}

/* ==========================================================================
   UTILITIES
   ========================================================================== */
.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;
}
.center { text-align: center; }
.center p, .center .lead { margin-inline: auto; }
.center .eyebrow--rule { justify-content: center; }
.mt-0 { margin-top: 0; }
.hairline { height: 1px; background: var(--hair); border: 0; margin: 0; }

/* Defensive: main carries the page ground itself, so a stale cached
   stylesheet or a partial body rule can't leave content on a bare canvas. */
main { background: var(--paper); }
