/* ============================================================
   GLOBAL.CSS
   Case by Case Homes — Verbolta Studio
   ─────────────────────────────────────────────────────────────
   Design system (2026-10 redesign)
   Palette comes straight from the client's logo: charcoal, gold
   and mountain grey, on a warm near-white "paper".
   Type pairs a wide, sturdy grotesk for headlines (Archivo,
   expanded: the construction side, echoing the logo's wide caps)
   with a refined italic serif for accent words (Newsreader: the
   real-estate polish), e.g. "Fund it. Fix it. *Sell it.*"

   Contents:
   1. Custom Properties (tokens)
   2. Reset
   3. Base Typography
   4. Utility Classes
   5. Scroll Entrance (reveal system)
   6. Preloader
   7. Scroll-to-Top Button
   8. Cookie Banner
   9. Skip Link
   10. Focus Styles
   11. Reduced Motion + no-JS fallbacks
   ============================================================ */


/* ─────────────────────────────────────────────────────────────
   1. CUSTOM PROPERTIES
   ───────────────────────────────────────────────────────────── */

:root {

  /* Color — sampled from the logo (charcoal #262C32, gold #BE9B57) */
  --color-paper:      #FAF9F6;   /* page background */
  --color-stone:      #EFEDE8;   /* alternate sections, panels */
  --color-white:      #FFFFFF;
  --color-charcoal:   #262C32;   /* text + dark sections (logo charcoal) */
  --color-ink:        #1C2025;   /* deepest dark: CTA band, overlays */
  --color-slate:      #5C636A;   /* secondary text on light */
  --color-mountain:   #A9AEB1;   /* logo grey — quiet rules on dark */
  --color-gold:       #BE9B57;   /* logo gold — accents, rules, marks */
  --color-gold-deep:  #7E602A;   /* gold TEXT on light (AA) */
  --color-gold-light: #D3B67C;   /* gold TEXT on dark (AA) */
  --color-rule:       #DCD9D2;   /* hairlines on light */
  --color-rule-dark:  rgba(250, 249, 246, 0.14); /* hairlines on dark */
  --color-error:      #B3261E;

  /* Drafting sheet — the warm paper the homepage hero and every page header
     are drawn on: a fine non-photo-blue grid, a little paper grain */
  --color-sheet:       #E8E2D5;
  --color-np-blue:     #7FA3C4;   /* non-photo blue: layout lines + grid */
  --color-np-blue-ink: #56799C;   /* the same blue, dark enough for lettering */
  --sheet-grid:
    linear-gradient(rgba(110, 148, 184, 0.24) 1px, transparent 1px),
    linear-gradient(90deg, rgba(110, 148, 184, 0.24) 1px, transparent 1px),
    linear-gradient(rgba(110, 148, 184, 0.12) 1px, transparent 1px),
    linear-gradient(90deg, rgba(110, 148, 184, 0.12) 1px, transparent 1px);
  --sheet-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.36 0 0 0 0 0.3 0 0 0 0 0.22 0 0 0 0.12 0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23g)'/%3E%3C/svg%3E");
  --sheet-vignette: radial-gradient(ellipse 140% 115% at 50% 40%, rgba(0, 0, 0, 0) 58%, rgba(84, 66, 40, 0.1) 100%);

  /* Legacy aliases — older component rules still read these names */
  --color-cream: var(--color-paper);
  --color-navy:  var(--color-charcoal);
  --color-muted: var(--color-slate);

  /* Typography */
  --font-display: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --font-body:    'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --font-accent:  'Newsreader', Georgia, 'Times New Roman', serif;
  --display-stretch: 125%;   /* Archivo width axis: expanded headlines */
  --label-stretch:   112%;   /* tracked caps labels, like the logo's */

  /* Type scale */
  --text-xs:   0.75rem;     /* 12px — tracked caps labels, legal */
  --text-sm:   0.875rem;    /* 14px — captions, secondary copy */
  --text-base: 1.0625rem;   /* 17px — body */
  --text-md:   1.25rem;     /* 20px — lead copy */
  --text-lg:   1.5rem;      /* 24px — small display */
  --text-xl:   2.75rem;     /* 44px — section heads */
  --text-2xl:  3.75rem;     /* 60px — large heads */
  --text-3xl:  5rem;        /* 80px */
  --text-4xl:  7rem;        /* 112px — hero headline */

  /* Spacing scale (8px base) */
  --space-xs:  0.5rem;    /*   8px */
  --space-sm:  1rem;      /*  16px */
  --space-md:  2rem;      /*  32px */
  --space-lg:  4rem;      /*  64px */
  --space-xl:  7rem;      /* 112px */
  --space-2xl: 11rem;     /* 176px */

  /* Layout */
  --max-width:       1320px;
  --max-width-text:  680px;
  --gutter:          2rem;       /* 32px — side padding */
  --gutter-sm:       1.25rem;    /* 20px — mobile side padding */
  --radius:          4px;        /* cards, inputs, buttons */
  --radius-lg:       10px;       /* media frames */

  /* Nav */
  --nav-height: 84px;

  /* Transitions */
  --ease-out:    cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --transition-base: 0.4s var(--ease-out);
  --transition-slow: 0.8s var(--ease-out);
  --transition-fast: 0.2s var(--ease-out);

  /* Shadows (cool, low — from the charcoal) */
  --shadow-sm: 0 1px 2px rgba(28, 32, 37, 0.06), 0 2px 8px rgba(28, 32, 37, 0.05);
  --shadow-md: 0 2px 6px rgba(28, 32, 37, 0.06), 0 16px 40px rgba(28, 32, 37, 0.10);

  /* Z-index stack */
  --z-below:   -1;
  --z-base:     0;
  --z-above:    10;
  --z-nav:      100;
  --z-overlay:  200;
  --z-modal:    300;
  --z-top:      400;
}


/* ─────────────────────────────────────────────────────────────
   2. RESET
   ───────────────────────────────────────────────────────────── */

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

html {
  font-size: 16px;
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  overflow-x: clip; /* kill any sideways scroll without breaking sticky/fixed */
}

body {
  background-color: var(--color-paper);
  color: var(--color-charcoal);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

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

img {
  height: auto;
}

a {
  color: inherit;
  text-decoration: none;
}

ul,
ol {
  list-style: none;
}

button {
  background: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

input,
textarea,
select {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

address {
  font-style: normal;
}

table {
  border-collapse: collapse;
}

/* The hidden attribute always wins over component display rules */
[hidden] {
  display: none !important;
}

::selection {
  background-color: var(--color-gold);
  color: var(--color-ink);
}


/* ─────────────────────────────────────────────────────────────
   3. BASE TYPOGRAPHY
   ───────────────────────────────────────────────────────────── */

/* Headlines — Archivo, expanded and confident */
h1, h2, h3 {
  font-family: var(--font-display);
  font-stretch: var(--display-stretch);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.025em;
  color: inherit;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.75rem, 6vw, var(--text-3xl));
}

h2 {
  font-size: clamp(2rem, 3.6vw, var(--text-xl));
}

h3 {
  font-size: clamp(1.25rem, 1.8vw, var(--text-lg));
  letter-spacing: -0.015em;
}

/* Functional headings — tracked caps, like the logo's tagline */
h4, h5, h6 {
  font-family: var(--font-body);
  font-stretch: var(--label-stretch);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-size: var(--text-xs);
}

/* Accent words inside headlines: the serif italic voice */
h1 em, h2 em, h3 em {
  font-family: var(--font-accent);
  font-style: italic;
  font-weight: 400;
  font-stretch: 100%;
  letter-spacing: -0.01em;
}

p {
  max-width: var(--max-width-text);
  line-height: 1.7;
  color: var(--color-slate);
  text-wrap: pretty;
}

sup, sub {
  font-size: 0.65em;
  vertical-align: super;
}

strong {
  font-weight: 600;
  color: var(--color-charcoal);
}

em {
  font-style: italic;
}

hr {
  border: none;
  border-top: 1px solid var(--color-rule);
  margin: var(--space-lg) 0;
}


/* ─────────────────────────────────────────────────────────────
   4. UTILITY CLASSES
   ───────────────────────────────────────────────────────────── */

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

/* Visually hidden (accessible) */
.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;
}

/* Tracked caps label — the logo's "CONSTRUCTION & REAL ESTATE" voice */
.text-label {
  font-family: var(--font-body);
  font-stretch: var(--label-stretch);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.text-muted { color: var(--color-slate); }

/* Section padding — standard vertical rhythm */
.section {
  padding-block: var(--space-xl);
}

.section--sm {
  padding-block: var(--space-lg);
}

.section--lg {
  padding-block: var(--space-2xl);
}

/* Follows a section on the same background: don't double the gap */
.section--flush-top {
  padding-top: 0;
}

/* Background utilities */
.bg-ink {
  background-color: var(--color-charcoal);
  color: var(--color-paper);
}

.bg-stone {
  background-color: var(--color-stone);
}

.bg-paper {
  background-color: var(--color-paper);
  color: var(--color-charcoal);
}

/* Hairline dividers */
.rule {
  width: 100%;
  height: 1px;
  background-color: var(--color-rule);
}

.rule--dark {
  background-color: var(--color-rule-dark);
}

/* Lazy image wrapper — prevents layout shift; blur-up while loading */
.img-wrap {
  overflow: hidden;
  position: relative;
  background-color: var(--color-stone);
}

.img-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: blur(8px);
  transition: filter var(--transition-slow);
}

.img-wrap img.loaded {
  filter: blur(0);
}


/* ─────────────────────────────────────────────────────────────
   5. SCROLL ENTRANCE — REVEAL SYSTEM
   Triggered by IntersectionObserver in main.js.
   Add class="reveal" to any element to opt in.
   Use data-delay="100" (ms) for staggered siblings.
   ───────────────────────────────────────────────────────────── */

.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity 0.8s var(--ease-out),
    transform 0.8s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.reveal--visible {
  opacity: 1;
  transform: translateY(0);
}

/* Fade only variant — no vertical movement */
.reveal-fade {
  opacity: 0;
  transition: opacity 0.9s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.reveal-fade--visible {
  opacity: 1;
}

/* Slide from left */
.reveal-left {
  opacity: 0;
  transform: translateX(-28px);
  transition:
    opacity 0.8s var(--ease-out),
    transform 0.8s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.reveal-left--visible {
  opacity: 1;
  transform: translateX(0);
}


/* ─────────────────────────────────────────────────────────────
   6. INTRO
   The once-per-visit brand intro (src/components/Intro.astro),
   on the same drafting sheet as the hero and page headers: blue
   construction lines (0–0.5s), the logo traced in graphite with
   the gold arrow (0.2–0.85s), the full-color logo resolving in
   (0.62–1s), then the sheet dissolves into the page. Hidden
   unless /intro.js set html.is-intro before first paint, so it
   can never flash on a page view that skips it.
   ───────────────────────────────────────────────────────────── */

.intro { display: none; }

.is-intro .intro,
.is-intro-out .intro {
  position: fixed;
  inset: 0;
  z-index: var(--z-top);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background-color: var(--color-sheet);
  background-image: var(--sheet-vignette), var(--sheet-grain);
}

/* The sheet's grid, strongest around the mark */
.intro::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: var(--sheet-grid);
  background-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px;
  background-position: center;
  -webkit-mask-image: radial-gradient(ellipse 55% 60% at 50% 50%, #000 20%, transparent 80%);
  mask-image: radial-gradient(ellipse 55% 60% at 50% 50%, #000 20%, transparent 80%);
}

.intro__mark {
  position: relative;
  width: min(300px, 62vw);
  aspect-ratio: 906 / 901;
}

.intro__logo,
.intro__lines {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.intro__lines { overflow: visible; }

.intro__logo {
  opacity: 0;
  transform: scale(0.97);
  animation: intro-logo 0.4s var(--ease-out) 0.62s forwards;
}

@keyframes intro-logo {
  to { opacity: 1; transform: none; }
}

/* Sketch-in: every stroke carries pathLength="1" */
.intro__draw {
  stroke-dasharray: 1 1;
  stroke-dashoffset: 1;
  animation: intro-draw 0.55s var(--ease-in-out) var(--d, 0s) forwards;
}

@keyframes intro-draw {
  to { stroke-dashoffset: 0; }
}

/* Construction lines in non-photo blue; they step back once the logo is in */
.intro__blue {
  fill: none;
  stroke: var(--color-np-blue);
  stroke-width: 2.6;
  animation: intro-recede 0.5s var(--ease-out) 0.95s forwards;
}

.intro__corners {
  stroke: var(--color-charcoal);
  stroke-opacity: 0.45;
  stroke-width: 3;
}

@keyframes intro-recede {
  to { opacity: 0.35; }
}

/* The trace hands over to the real logo */
.intro__trace {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: intro-trace-out 0.4s var(--ease-out) 0.9s forwards;
}

@keyframes intro-trace-out {
  to { opacity: 0; }
}

.intro__ink { stroke: var(--color-charcoal); stroke-width: 3.8; }
.intro__ink--fine { stroke-width: 3; }
.intro__grey { stroke: var(--color-mountain); stroke-width: 3.6; }
.intro__gold { stroke: var(--color-gold); stroke-width: 4.4; }

/* The hand-off: the sheet dissolves, the logo lifts toward you */
.is-intro-out .intro {
  pointer-events: none;
  animation: intro-out 0.6s var(--ease-in-out) forwards;
}

.is-intro-out .intro__mark {
  animation: intro-mark-out 0.6s var(--ease-in-out) forwards;
}

@keyframes intro-out {
  to { opacity: 0; visibility: hidden; }
}

@keyframes intro-mark-out {
  to { transform: scale(1.06); }
}


/* ─────────────────────────────────────────────────────────────
   7. SCROLL-TO-TOP BUTTON
   Appears after 400px scroll. Smooth-scrolls to top on click.
   ───────────────────────────────────────────────────────────── */

.scroll-top {
  position: fixed;
  bottom: 2rem;
  right: 2rem;
  z-index: var(--z-above);
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 1px solid var(--color-rule);
  background-color: var(--color-paper);
  color: var(--color-charcoal);
  box-shadow: var(--shadow-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition:
    opacity var(--transition-base),
    transform var(--transition-base),
    background-color var(--transition-fast),
    color var(--transition-fast),
    border-color var(--transition-fast);
  cursor: pointer;
}

/* Only invert on real-hover devices — otherwise a tap on touchscreens leaves
   the button stuck in its hover state. */
@media (hover: hover) {
  .scroll-top:hover {
    background-color: var(--color-charcoal);
    border-color: var(--color-charcoal);
    color: var(--color-paper);
  }
}

.scroll-top--visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* Arrow icon drawn with CSS — no SVG dependency */
.scroll-top::before {
  content: '';
  display: block;
  width: 9px;
  height: 9px;
  border-left: 1.5px solid currentColor;
  border-top: 1.5px solid currentColor;
  transform: rotate(45deg) translate(2px, 2px);
}


/* ─────────────────────────────────────────────────────────────
   8. COOKIE BANNER
   A compact card, bottom-left. JS hides it after a choice.
   ───────────────────────────────────────────────────────────── */

.cookie-banner {
  position: fixed;
  left: var(--space-md);
  bottom: var(--space-md);
  z-index: var(--z-overlay);
  width: min(420px, calc(100vw - 2 * var(--gutter)));
  background-color: var(--color-charcoal);
  color: var(--color-paper);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: var(--space-sm) var(--space-md) var(--space-sm) var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  opacity: 0;
  transform: translateY(16px);
  pointer-events: none;
  transition: opacity 0.4s var(--ease-out), transform 0.5s var(--ease-out);
}

.cookie-banner--visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.cookie-banner__text {
  font-size: var(--text-sm);
  color: rgba(250, 249, 246, 0.78);
  max-width: none;
  line-height: 1.5;
}

.cookie-banner__text a {
  color: var(--color-gold-light);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.cookie-banner__actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

/* Accept uses the outlined button, inverted for the dark card */
.cookie-banner .btn-outline-inv {
  border-color: var(--color-paper);
  color: var(--color-paper);
  padding: 0.6rem 1.25rem;
}

.cookie-banner .btn-outline-inv:hover {
  background-color: var(--color-paper);
  color: var(--color-charcoal);
}

.cookie-banner__dismiss {
  font-size: var(--text-sm);
  color: rgba(250, 249, 246, 0.7);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  transition: color var(--transition-fast);
}

.cookie-banner__dismiss:hover {
  color: var(--color-paper);
}

@media (max-width: 640px) {
  .cookie-banner {
    left: var(--gutter-sm);
    right: var(--gutter-sm);
    bottom: var(--gutter-sm);
    width: auto;
  }
}


/* ─────────────────────────────────────────────────────────────
   9. SKIP LINK
   ───────────────────────────────────────────────────────────── */

.skip-link {
  position: absolute;
  top: -100%;
  left: var(--space-sm);
  z-index: var(--z-top);
  background-color: var(--color-charcoal);
  color: var(--color-paper);
  padding: var(--space-xs) var(--space-sm);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  border-radius: var(--radius);
  transition: top var(--transition-fast);
}

.skip-link:focus {
  top: var(--space-sm);
}


/* ─────────────────────────────────────────────────────────────
   10. FOCUS STYLES
   Visible, brand-appropriate, keyboard only.
   ───────────────────────────────────────────────────────────── */

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

:focus:not(:focus-visible) {
  outline: none;
}

/* Brighter ring on dark backgrounds */
.bg-ink :focus-visible,
.footer--dark :focus-visible,
.financing-band :focus-visible,
.contact-strip :focus-visible,
.hero :focus-visible,
.nav--over-hero :focus-visible {
  outline-color: var(--color-gold-light);
}

/* …except the homepage's light drawing hero */
.hero--light :focus-visible {
  outline-color: var(--color-gold-deep);
}


/* ─────────────────────────────────────────────────────────────
   11. REDUCED MOTION + NO-JS FALLBACKS
   ───────────────────────────────────────────────────────────── */

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

  .reveal,
  .reveal-fade,
  .reveal-left {
    opacity: 1;
    transform: none;
  }

  .img-wrap img {
    filter: none;
  }
}

/* Without JavaScript nothing would ever reveal or un-blur images — so show
   everything as-is. (The intro never shows without JS: /intro.js turns it on.) */
@media (scripting: none) {
  .reveal,
  .reveal-fade,
  .reveal-left {
    opacity: 1;
    transform: none;
  }

  .img-wrap img { filter: none; }
}


/* ─────────────────────────────────────────────────────────────
   RESPONSIVE ADJUSTMENTS
   ───────────────────────────────────────────────────────────── */

@media (max-width: 768px) {
  :root {
    --gutter: var(--gutter-sm);
    --nav-height: 72px;
  }

  .section {
    padding-block: 4.5rem;
  }

  .section--lg {
    padding-block: var(--space-xl);
  }

  .scroll-top {
    bottom: 1.25rem;
    right: 1.25rem;
  }

  /* On mobile, reveal by sliding UP rather than in from the left — the
     horizontal slide reads as the page shifting sideways on narrow screens. */
  .reveal-left {
    transform: translateY(20px);
  }

  .reveal-left--visible {
    transform: translateY(0);
  }
}
