/*
 * Cedar & Nails — base styles + shared components.
 * Style-guide rules encoded once here: monochrome UI where photography carries
 * all the color (§1), pill geometry for controls and large-radius cards for
 * imagery (§5), translucent glass chrome over photos (§5), near-none motion
 * respecting prefers-reduced-motion, one dark pill per viewport (§5).
 * Section anatomy lives in each page.
 */

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

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* Sticky footer: short pages (the stripe/* landings especially) keep the
 * footer at the viewport bottom. Body is a column; main takes the slack. */
body {
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: 1.6;
  color: var(--color-ink);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
main { flex: 1 0 auto; }
/* Body scroll locks while the overlay menu is open (scripts/nav.js). */
body.nav-open { overflow: hidden; }

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

h1, h2, h3 { line-height: 1.12; font-weight: 650; margin: 0; letter-spacing: -0.015em; }
p { margin: 0; }

a { color: var(--color-ink); text-decoration: none; }
a:hover { text-decoration: underline; }

/* --- Layout ------------------------------------------------------------- */
.wrap { width: 100%; max-width: var(--max-content); margin-inline: auto; padding-inline: clamp(1.25rem, 4vw, 2.5rem); }
.section { padding-block: var(--section-pad); }
.prose { max-width: var(--max-prose); }
.prose h2 { font-size: var(--text-h3); margin: 2.5rem 0 0.75rem; }
.prose p, .prose li { color: var(--color-ink-soft); margin-bottom: 0.75rem; }
.prose a { text-decoration: underline; }
.rule { border: 0; border-top: 1px solid var(--color-line); margin: 0; }

/* --- Type helpers ------------------------------------------------------- */
.eyebrow {
  font-size: var(--text-meta);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-ink-soft);
  margin: 0 0 1rem;
}
.lead { font-size: var(--text-body-lg); color: var(--color-ink-soft); }
.meta { font-size: var(--text-meta); color: var(--color-ink-soft); }

/* The display headline pattern (§4): first line quiet serif, second line bold
 * sans. Use <h1 class="headline"><span class="headline__serif">…</span>
 * <strong>…</strong></h1>. */
.headline { font-size: var(--text-hero); font-weight: 700; letter-spacing: -0.02em; }
.headline__serif { display: block; font-family: var(--font-serif); font-weight: 420; letter-spacing: -0.01em; }
.headline--h2 { font-size: var(--text-h2); }

/* --- Buttons (§5: pills; at most one dark pill per viewport) ------------- */
.btn {
  display: inline-block;
  font: inherit;
  font-weight: 550;
  padding: 13px 26px;
  border-radius: var(--radius-pill);
  border: 0;
  background: var(--color-surface);
  color: var(--color-ink);
  cursor: pointer;
  transition: background-color 200ms ease, color 200ms ease;
}
@media (prefers-reduced-motion: reduce) { .btn { transition: none; } }
.btn:hover { text-decoration: none; background: var(--color-surface-2); }
.btn--dark { background: var(--color-btn-dark); color: var(--color-ink-inverse); }
.btn--dark:hover { background: var(--color-btn-dark-hover); color: var(--color-ink-inverse); }

/* --- Nav (three-tier rework, owner 2026-07-21) ---------------------------
 * One shared header markup on every page — brand (both logo <img>s), the
 * three pills, and the round glass menu button — with CSS-only tier
 * switching (display:none keeps hidden controls out of the tab order):
 *   tier 1 (wide):   full lockup + three pills            (no hamburger)
 *   tier 2 (medium): mark alone + three pills             (no hamburger)
 *   tier 3 (small):  mark alone + glass hamburger only    (overlay menu)
 * The lockup NEVER scales down and the pills never wrap or shrink — the
 * breakpoints below are measured, not guessed (rationale at the queries). */
.nav {
  position: sticky; top: 0; z-index: 10;
  background: rgba(255, 255, 255, 0.97);
}
.nav__inner { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; min-height: 72px; }
.brand { display: inline-flex; align-items: center; }
.brand:hover { text-decoration: none; }
.brand__logo { height: 40px; width: auto; } /* pill height — owner-tuned 2026-07-18 */
.brand__logo--invert { filter: invert(1); }
.brand__logo--mark { display: none; }
/* Mark at header scale (tier-2/3 header + overlay top row) — owner rule
 * 2026-07-21: the glyph's tip-to-tip height must equal the .nav-toggle
 * circle's 44px diameter, on the same optical centerline. mark.svg's ink
 * spans y 27.15→78 of its 100u viewBox (roof-apex ink at 30 − 5.7/2 stroke
 * radius; nail tip at 78) = 50.85% of the file box — the rest is
 * transparent padding. So: keep the 44px layout box, scale(1/0.5085 ≈
 * 1.967) to make the GLYPH span 44px, and nudge up by the glyph center's
 * offset below the box center (2.575u → 2.575% × 44px × 1.967 ≈ 2.2px). */
.brand__logo--mark,
.site-menu__top .brand__logo {
  height: 44px;
  transform: translateY(-2.2px) scale(1.967);
}
.nav__links { display: flex; align-items: center; gap: 0.5rem; }
.nav__links .btn { padding: 9px 18px; font-size: 0.9375rem; white-space: nowrap; flex: none; }
/* Current page: the pill you're on holds the pressed (hover-depth) fill and a
 * heavier weight — monochrome state, no accent. Pages set aria-current="page". */
.nav__links a[aria-current="page"] { background: var(--color-surface-2); font-weight: 650; }
.nav .nav-toggle { display: none; } /* hamburger appears only at tier 3 */

/* Tier 2 — measured 2026-07-21 (Inter loaded, which renders wider than the
 * system-ui fallback): lockup 232.12px (40px tall at the SVG's 766:132
 * ratio) + 24px flex gap + pills row 390.06px (133 + 121.66 + 119.41 +
 * 2×8px gaps) + 2×clamp(20px, 4vw, 40px) wrap padding. Solving
 * vw ≥ 646.2 + 0.08·vw gives an exact fit at 703px; +15px for classic
 * scrollbars (media queries measure the viewport including them) ≈ 718.
 * Below 720 the mark replaces the lockup — the lockup never scales down. */
@media (max-width: 719.98px) {
  .brand__logo--lockup { display: none; }
  .brand__logo--mark { display: block; }
}

/* Tier 3 — measured: mark 40px + 24px gap + pills 390.06px + 2×20px padding
 * (clamp floor below 500px vw) = 494px exact fit; +15px scrollbar allowance
 * ≈ 509. Below 512 the pills would wrap or shrink, so they swap for the
 * glass hamburger and the overlay menu takes over. */
@media (max-width: 511.98px) {
  .nav__links { display: none; }
  .nav .nav-toggle { display: inline-flex; }
}

/* Round glass menu button (§5 glass chrome). Three bars morph into an X while
 * the menu is open; reduced motion drops the animation, not the state. */
.nav-toggle {
  width: 44px; height: 44px; flex: none;
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; padding: 0;
  border: 0; border-radius: var(--radius-pill); cursor: pointer;
  background: var(--glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.nav-toggle__bar {
  width: 16px; height: 2px; border-radius: 1px;
  background: #FFFFFF;
  transition: transform 200ms ease, opacity 200ms ease;
}
/* Bar centers sit 6px apart (2px bar + 4px gap), so ±6px folds them into an X. */
body.nav-open .nav-toggle__bar:nth-child(1) { transform: translateY(6px) rotate(45deg); }
body.nav-open .nav-toggle__bar:nth-child(2) { opacity: 0; }
body.nav-open .nav-toggle__bar:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }
@media (prefers-reduced-motion: reduce) { .nav-toggle__bar { transition: none; } }

/* --- Full-screen overlay menu --------------------------------------------
 * Fixed, covers the viewport, glass blur over the page (solid ink fallback
 * where backdrop-filter is unsupported), monochrome. Top row mirrors the
 * header: mark left, morphed-X button right. */
.site-menu {
  position: fixed; inset: 0; z-index: 40;
  display: flex; flex-direction: column;
  background: rgba(20, 20, 19, 0.97);
  color: var(--color-ink-inverse);
  visibility: hidden; opacity: 0;
  transition: opacity 200ms ease, visibility 0s linear 200ms;
}
@supports ((backdrop-filter: blur(24px)) or (-webkit-backdrop-filter: blur(24px))) {
  .site-menu {
    background: rgba(24, 24, 23, 0.8);
    backdrop-filter: blur(24px);
    -webkit-backdrop-filter: blur(24px);
  }
}
.site-menu.is-open { visibility: visible; opacity: 1; transition: opacity 200ms ease; }
@media (prefers-reduced-motion: reduce) { .site-menu { transition: none; } }
.site-menu__top { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; min-height: 72px; flex: none; }
.site-menu__links {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
  gap: 0.75rem;
}
/* Menu links live in the headline type system: hero-size bold sans. Inactive
 * links are translucent white, the current page and hover are solid — the
 * same weight-and-opacity move as the glass seg control. */
.site-menu__link {
  font: inherit; font-size: var(--text-hero); font-weight: 700;
  letter-spacing: -0.02em; line-height: 1.15;
  color: rgba(255, 255, 255, 0.85);
  background: none; border: 0; padding: 0; cursor: pointer; text-align: left;
  transition: color 200ms ease;
}
.site-menu__link:hover, .site-menu__link:focus-visible { color: #FFFFFF; text-decoration: none; }
.site-menu__link[aria-current="page"] { color: #FFFFFF; }
.site-menu__link--app { margin-top: clamp(1.5rem, 6vh, 3rem); }
@media (prefers-reduced-motion: reduce) { .site-menu__link { transition: none; } }
.site-menu__legal { flex: none; border-top: 1px solid rgba(255, 255, 255, 0.14); padding-block: 1.5rem; font-size: var(--text-meta); color: #9C9C97; }
.site-menu__legal a { color: #C9C9C4; }

/* --- Photo cards & placeholders (§6: photography sits in rounded slabs) --
 * Until a photographer shoots the top jobs, every image slot renders as a
 * labelled neutral-gray block. The label names WHAT image goes there so the
 * swap is unambiguous. data-free: replace the .ph div with an <img> inside the
 * same .media-card. */
.media-card { border-radius: var(--radius-l); overflow: hidden; position: relative; }
.ph {
  position: relative;
  background:
    repeating-linear-gradient(135deg, transparent 0 22px, rgba(20, 20, 19, 0.03) 22px 23px),
    linear-gradient(160deg, #EFEFED, #DEDEDA);
  display: grid; place-items: center;
  color: var(--color-ink-soft);
  overflow: hidden;
}
.ph--char { background: linear-gradient(160deg, #333331, #1B1B1A); color: var(--color-ink-inverse); }
.ph__label {
  font-size: var(--text-meta); letter-spacing: 0.04em;
  padding: 0.6rem 0.9rem; text-align: center; max-width: 30ch;
}
.ph__label::before { content: "◈ photo — "; opacity: 0.6; }
.ph--app .ph__label::before { content: "◈ app screenshot — "; }
.ph--16x9 { aspect-ratio: 16 / 9; }
.ph--4x3 { aspect-ratio: 4 / 3; }
.ph--3x2 { aspect-ratio: 3 / 2; }
.ph--hero { min-height: clamp(360px, 60vh, 640px); }
/* Anchor hero/panel captions low so they never collide with glass chrome
 * overlaid at the top of the card. */
.ph--hero, .ph--panel { place-items: end center; }
.ph--hero .ph__label, .ph--panel .ph__label { padding-bottom: 1.75rem; opacity: 0.85; }
.ph--panel { aspect-ratio: 16 / 9; min-height: clamp(320px, 52vh, 560px); }

/* --- Glass segmented control (§5: translucent chrome over photography) ---
 * The rounded rect that floats at the top of an image card and switches the
 * content beneath it. Inactive labels are translucent white; the active one is
 * solid white and bold. No chip behind the active item — weight and opacity do
 * the work. */
.seg {
  display: inline-flex; align-items: center; gap: 0.25rem;
  padding: 6px 10px;
  border-radius: var(--radius-pill);
  background: var(--glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.seg__btn {
  font: inherit; font-size: 0.9375rem; font-weight: 500;
  color: rgba(255, 255, 255, 0.62);
  background: none; border: 0; cursor: pointer;
  padding: 7px 14px; border-radius: var(--radius-pill);
  transition: color 200ms ease;
}
@media (prefers-reduced-motion: reduce) { .seg__btn { transition: none; } }
.seg__btn:hover { color: rgba(255, 255, 255, 0.85); }
.seg__btn[aria-selected="true"] { color: #FFFFFF; font-weight: 650; }
.seg--overlay { position: absolute; top: clamp(0.9rem, 2.5vw, 1.5rem); left: 50%; transform: translateX(-50%); z-index: 2; }

/* --- Reveal on scroll (fade-up once, whole sections) --------------------- */
.reveal { opacity: 0; transform: translateY(12px); transition: opacity 400ms ease-out, transform 400ms ease-out; }
.reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* --- Get-the-app modal (§6.2) ------------------------------------------- */
.app-modal {
  border: 0; padding: 0; margin: auto;
  width: min(92vw, 480px);
  border-radius: var(--radius-l);
  background: var(--color-bg); color: var(--color-ink);
}
.app-modal::backdrop { background: rgba(20, 20, 19, 0.45); backdrop-filter: blur(4px); }
.app-modal__body { padding: clamp(1.5rem, 4vw, 2.25rem); }
.app-modal__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 0.5rem; }
.app-modal__title { font-size: var(--text-h3); font-weight: 650; }
.app-modal__close {
  font: inherit; font-size: 1.25rem; line-height: 1;
  background: var(--color-surface); color: var(--color-ink);
  border: 0; border-radius: var(--radius-pill); cursor: pointer;
  width: 36px; height: 36px; flex: none;
}
.app-modal__close:hover { background: var(--color-surface-2); }
.app-modal__sub { color: var(--color-ink-soft); margin-bottom: 1.5rem; }
/* Rows are non-interactive <div>s until the apps ship — the store line reads
 * as a status label, so no hover state and no link arrow. */
.app-modal__item {
  display: block; padding: 1.1rem 1.25rem; margin-top: 0.75rem;
  border-radius: var(--radius-m); background: var(--color-surface);
}
.app-modal__item-title { font-weight: 650; }
.app-modal__item-sub { font-size: var(--text-meta); color: var(--color-ink-soft); margin-top: 0.15rem; }
.app-modal__item-store { font-size: var(--text-meta); font-weight: 550; color: var(--color-ink-soft); margin-top: 0.6rem; }

/* --- Footer (§6.9: dark, quiet) ------------------------------------------ */
.footer { background: var(--color-char); color: var(--color-ink-inverse); }
.footer a { color: var(--color-ink-inverse); }
/* Pills on the dark footer keep their own ink (§5: a secondary pill is
 * surface fill + ink text, same as the CTA bands' light pill on --color-char).
 * Without this, `.footer a` (0,1,1) out-specifies `.btn` (0,1,0) and paints
 * the label inverse-on-light — near-invisible. Covers hover too. */
.footer .btn, .footer .btn:hover { color: var(--color-ink); }
/* The brand sits in its own row ABOVE the grid so every grid cell leads with
   an h4 — the section headers land on the same line in every column count. */
.footer__brand { padding-block: 3.5rem 0; }
.footer__brand p { font-size: var(--text-meta); color: #C9C9C4; margin: 0; }

/* Homeowner footer (owner 2026-07-21): the legal line IS the footer — the
   CTA band above carries contact; everything else lives in the nav. */
.footer--cta .footer__legal .wrap { text-align: center; }
.footer__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 2rem; padding-block: 2.5rem 3.5rem; }
.footer__grid h4 { font-size: var(--text-meta); text-transform: uppercase; letter-spacing: 0.08em; color: #9C9C97; margin: 0 0 0.75rem; font-weight: 600; }
.footer__grid p, .footer__grid li { font-size: var(--text-meta); color: #C9C9C4; margin: 0 0 0.4rem; list-style: none; }
.footer__grid ul { margin: 0; padding: 0; }
.footer__license { color: var(--color-ink-inverse); font-weight: 600; }
.footer__legal { border-top: 1px solid #333330; padding-block: 1.5rem; font-size: var(--text-meta); color: #9C9C97; }
.footer__legal a { color: #C9C9C4; }
