/* ==========================================================================
   SVEF — reset, document defaults, layout primitives  ·  THRESHOLD

   Loaded after tokens.css. Selectors here are deliberately low specificity
   (elements and single classes) so components.css never has to fight them.

   The design commits to one dark world, so every surface paints its own
   ground explicitly. Nothing here assumes a white page underneath.
   ========================================================================== */

/* ------------------------------------------------------------------ reset */

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

html {
  /* The rem tokens resolve against THIS element, so it has to carry the
     design's base size. Setting 17px on <body> instead left every rem
     token computing against the browser's 16px default — so --fs-body
     rendered a pixel smaller than the body copy it was named for, and the
     whole scale sat about 6% under what the design intended. */
  font-size: 106.25%;   /* 17px on a default 16px browser */
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchor targets clear the sticky header instead of hiding beneath it. */
  scroll-padding-top: calc(var(--header-h-shrunk) + var(--space-6));
}

body {
  margin: 0;
  background: var(--obsidian);
  color: var(--smoke);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: var(--fw-regular);
  line-height: var(--lh-relaxed);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;   /* belt and braces against a stray wide child */
}

/* Headings are Poppins, not Montserrat. The display face is reserved for
   display type — hero lines, section titles, the accent clause — and is
   opted into by the component that wants it. An h4 in a card set in the
   display face would spend the page's one change of voice on something
   that does not need it. */
h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--fw-medium);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-tight);
  color: var(--bone);
  text-wrap: balance;   /* stops a lone orphan word on a heading's last line */
}

p { margin: 0 0 var(--space-4); }
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0; padding: 0; }
li { list-style: none; }

a {
  color: inherit;
  text-decoration: none;
  transition: color var(--dur-base) var(--ease-curtain);
}
a:hover { color: var(--champagne); }

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

/* SVG is deliberately not given height:auto. The icon helper emits its own
   width and height attributes, and height:auto discards them — every icon
   then resolves its height from an intrinsic ratio it does not have. */
svg { display: block; max-width: 100%; }

button, input, select, textarea {
  font: inherit;
  color: inherit;
}

button { cursor: pointer; background: none; border: 0; padding: 0; }

strong, b { font-weight: var(--fw-medium); color: var(--bone); }

em { font-style: italic; }

hr {
  border: 0;
  border-top: 1px solid var(--hair);
  margin: var(--space-8) 0;
}

::selection { background: var(--champagne); color: var(--obsidian); }

/* ------------------------------------------------------------- focus ring
   Only for keyboard users: :focus-visible keeps the ring off mouse clicks
   while guaranteeing it for anyone navigating by Tab. Champagne on a dark
   offset survives every surface in the site, including over a photograph. */

:focus { outline: none; }

:focus-visible {
  outline: 2px solid var(--champagne);
  outline-offset: 3px;
}

/* --------------------------------------------------------- accessibility */

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

/* The honeypot. Positioned off-screen rather than display:none or
   type="hidden", because capable bots skip both of those and would sail
   straight past the trap. Hidden from assistive tech and from Tab order. */
.hp-field {
  position: absolute !important;
  left: -9999px !important;
  top: auto;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* Keyboard users land here first and can jump straight to the content. */
.skip-link {
  position: absolute;
  left: var(--space-4);
  top: -100px;
  z-index: var(--z-toast);
  background: var(--champagne);
  color: var(--obsidian);
  padding: var(--space-3) var(--space-5);
  font-family: var(--font-body);
  font-size: var(--fs-xxs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  transition: top var(--dur-base) var(--ease-curtain);
}
.skip-link:focus { top: var(--space-4); color: var(--obsidian); }

/* --------------------------------------------------------- film grain
   Static, not animated — animated grain is a tell, and this is here to
   give the darkness a surface and to stop the large gradients banding on
   cheap panels, not to twinkle. Inert to the pointer. */
.grain {
  position: fixed;
  inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: 0.038;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ------------------------------------------------------------ containers */

.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container-narrow {
  width: 100%;
  max-width: calc(var(--container-narrow) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ------------------------------------------------------------- sections */

.section { padding-block: var(--section-y); }
.section-tight { padding-block: calc(var(--section-y) * 0.55); }

/* A control strip — filter tabs, a toolbar — belongs to the band beneath it
   rather than being a band of its own. Wrapped in .section-tight it charged
   section padding twice, once below itself and once above the listing, on
   top of the margin .filter-tabs already carries for exactly this job. The
   three stacked into a 216px hole between the tabs and the first heading.
   Pad above only, and let the strip's own margin set the distance below. */
.section-filter { padding-block: calc(var(--section-y) * 0.55) 0; }
.section-filter + .section,
.section-filter + .section-tight { padding-top: 0; }

/* The header is fixed, so whatever sits at the top of a page has to clear
   it. Both hero types already reserve that space themselves — the home
   hero runs full-bleed underneath it by design, and .page-hero pads for it
   — so only a page that opens on something else needs the allowance. A
   blanket rule on <main> gave every interior page the gap twice: once from
   main, once from the hero's own padding. */
main > *:first-child:not(.hero):not(.page-hero) {
  padding-top: calc(var(--header-h) + var(--space-10));
}

/* Surface variants. Kept as separate single-class modifiers so a section
   can change ground without any selector specificity conflict. The names
   survive from the previous design so every page keeps working; what they
   resolve to is now a step through the dark rather than a step through
   the light. */
.section-light { background: var(--obsidian); }
.section-alt   { background: var(--slate); }
.section-sand  { background: var(--slate-2); }

.section-navy      { background: var(--slate); }
.section-navy-deep { background: #06070A; }

/* A band's seam. The champagne hairline that separates one room from the
   next is the same device the logo draws with. */
.section-alt,
.section-sand,
.section-navy,
.section-navy-deep { border-block: 1px solid var(--hair); }

/* ----------------------------------------------------------------- grids
   Auto-fit grids collapse on their own, so most layouts need no media
   query at all. min() keeps a single card from overflowing a narrow phone. */

.grid { display: grid; gap: var(--space-8); }

.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }
.grid-5 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); }

.grid-gap-lg { gap: clamp(2rem, 5vw, 4.5rem); }
.grid-gap-sm { gap: var(--space-4); }

/* A content column beside a sidebar (Events, Insights). */
.grid-sidebar {
  display: grid;
  gap: clamp(2rem, 5vw, 4.5rem);
  grid-template-columns: 1fr;
}
@media (min-width: 62rem) {
  .grid-sidebar { grid-template-columns: minmax(0, 1fr) 21rem; }
  .grid-sidebar-left { grid-template-columns: 21rem minmax(0, 1fr); }
}

/* Two-column text-and-image blocks (About). */
.grid-split {
  display: grid;
  gap: clamp(2.5rem, 6vw, 6rem);
  grid-template-columns: 1fr;
  align-items: center;
}
@media (min-width: 54rem) {
  .grid-split { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ------------------------------------------------------- the aperture
   The site has ONE motion device, and this is it: a letterbox mask that
   draws back to admit you. The page opens through it, every photograph
   below the fold reveals through it, and each headline line rises from
   behind it. One idea used consistently reads as choreography; five
   different ideas read as a demo reel.

   Applied only to [data-reveal] elements, which the motion layer opens on
   arrival. Nothing here is applied by CSS alone, so a visitor whose script
   never runs is handled by the no-JS block at the end of motion.css
   rather than being left staring at an empty column. */

[data-reveal].reveal-mask {
  clip-path: inset(50% 0 50% 0);
  transition: clip-path var(--dur-mask) var(--ease-curtain);
}
[data-reveal].reveal-mask.is-in { clip-path: inset(0 0 0 0); }

[data-reveal].reveal,
.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity var(--dur-reveal) var(--ease-curtain),
              transform var(--dur-reveal) var(--ease-curtain);
}
[data-reveal].reveal.is-in,
.reveal.is-in,
.reveal.is-visible { opacity: 1; transform: none; }

[data-reveal].reveal-left  { transform: translateX(-26px); }
[data-reveal].reveal-right { transform: translateX(26px); }
[data-reveal].reveal-left.is-in,
[data-reveal].reveal-right.is-in { transform: none; }

[data-reveal].reveal-draw {
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-draw) var(--ease-curtain);
}
[data-reveal].reveal-draw.is-in { transform: scaleX(1); }

/* A room boundary announces itself with a champagne seam that draws
   across the full width as the room arrives. */
.seam { position: relative; }
.seam::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(to right, var(--champagne-dim), var(--hair) 62%, transparent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1800ms var(--ease-curtain);
}
.seam.is-in::before { transform: scaleX(1); }

/* ------------------------------------------------------------- utilities */

.text-center { text-align: center; }
.text-left   { text-align: left; }
.text-gold   { color: var(--champagne); }
.text-white  { color: var(--bone); }
.text-muted  { color: var(--smoke-2); }

.mx-auto { margin-inline: auto; }
.mt-0  { margin-top: 0; }
.mt-4  { margin-top: var(--space-4); }
.mt-6  { margin-top: var(--space-6); }
.mt-8  { margin-top: var(--space-8); }
.mt-10 { margin-top: var(--space-10); }
.mb-0  { margin-bottom: 0; }
.mb-4  { margin-bottom: var(--space-4); }
.mb-6  { margin-bottom: var(--space-6); }
.mb-8  { margin-bottom: var(--space-8); }
.mb-10 { margin-bottom: var(--space-10); }

.measure { max-width: 46ch; }
.measure-wide { max-width: 62ch; }

.is-hidden { display: none !important; }

.lead {
  font-size: var(--fs-lead);
  line-height: var(--lh-relaxed);
  color: var(--smoke);
  max-width: 52ch;
}
