/* Oak & Aperture — "gallery" theme.
 *
 * Sophisticated minimalism: the photography is the content and everything here
 * gets out of its way. Three rules carry the whole look.
 *
 *   1. Zero border radius. Architectural photography is lines and vertices;
 *      the interface mirrors it. No exceptions on buttons, cards, or images.
 *   2. 120px between sections. The whitespace is doing the positioning work,
 *      so it does not get compressed to fit more above the fold.
 *   3. Gold is rationed. It marks intent — a label, a hover, a divider — and
 *      the moment it becomes a background it stops reading as premium.
 *
 * Token values come from the design system chart, recorded in
 * MartinezVault/Project Notes/Real Estate Media/OakAndAperture_Brand_Tokens.md.
 * That note is canonical: the Stitch export shipped a different (wrong) gold
 * and a different primary, and this file follows the chart.
 */

/* ---------------------------------------------------------------- fonts --
 * Self-hosted per the mdsite convention: no Google Fonts CDN on any of these
 * sites. The two woff2 files are not in the repo yet, so the fallback stacks
 * below are real fallbacks and not decoration — the site is legible and
 * correctly proportioned without them, just not in the brand faces.
 *
 * Fetch to themes/gallery/static/fonts/:
 *   playfairdisplay-var.woff2   (Playfair Display, variable, latin)
 *   montserrat-var.woff2        (Montserrat, variable, latin)
 */
@font-face {
  font-family: "Playfair Display";
  src: url("/static/fonts/playfairdisplay-var.woff2") format("woff2");
  font-weight: 400 700;
  font-display: swap;
}
@font-face {
  font-family: "Montserrat";
  src: url("/static/fonts/montserrat-var.woff2") format("woff2");
  font-weight: 300 700;
  font-display: swap;
}

/* --------------------------------------------------------------- tokens -- */
:root {
  /* Core palette */
  --forest:    #1A2F23;   /* Primary — Forest Oak */
  --gold:      #C5A059;   /* Secondary — Aperture Gold */
  --gallery:   #F9F8F6;   /* Tertiary — Gallery White */
  --obsidian:  #121212;   /* Neutral — body text */

  /* Derived */
  --forest-deep:  #0F1D15;
  --forest-soft:  #2A4535;
  --gold-light:   #E7CD9B;
  --gold-dark:    #806539;
  --hairline:     #E5E5E5;
  --muted:        #6B6B6B;
  --on-dark-soft: rgba(249, 248, 246, 0.72);

  /* Type */
  --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --font-body:    "Montserrat", "Helvetica Neue", Arial, sans-serif;

  /* Space */
  --container:     1280px;
  --gutter:        32px;
  --margin:        64px;
  --margin-mobile: 24px;
  --section:       120px;

  /* Shape and depth */
  --radius: 0;
  --lift:   0 32px 64px -12px rgba(18, 18, 18, 0.04);
}

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

body {
  margin: 0;
  background: var(--gallery);
  color: var(--obsidian);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }
a   { color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  margin: 0;
  color: var(--forest);
}

h1 { font-size: 40px; font-weight: 700; line-height: 1.2; letter-spacing: -0.01em; }
h2 { font-size: 32px; font-weight: 600; line-height: 1.3; }
h3 { font-size: 24px; font-weight: 500; line-height: 1.4; }

@media (min-width: 768px) {
  h1 { font-size: 64px; line-height: 1.1; letter-spacing: -0.02em; }
}

p { margin: 0 0 1.2em; }
p:last-child { margin-bottom: 0; }

/* The signature detail of the system: every label is uppercase with wide
 * tracking, which is what reads as a luxury watermark rather than a caption. */
.label {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.label-gold   { color: var(--gold); }
.label-onDark { color: var(--gold-light); }

.lede { font-size: 18px; letter-spacing: 0.01em; }
.muted { color: var(--muted); }

/* ------------------------------------------------------------- layout --- */
.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--margin-mobile);
}
@media (min-width: 768px) {
  .container { padding: 0 var(--margin); }
}

section { padding: 64px 0; }
@media (min-width: 768px) {
  section { padding: var(--section) 0; }
}

.section-dark  { background: var(--forest); color: var(--gallery); }
.section-dark h1, .section-dark h2,
.section-dark h3, .section-dark h4 { color: var(--gallery); }
.section-tint  { background: #F2F0ED; }

/* Two dark sections in a row read as one undifferentiated slab — on the home
 * page the flagship panel runs straight into the closing call to action. When
 * that happens the second one drops to the deeper tone, which is the tonal-layer
 * approach the design system already uses instead of adding a border. */
.section-dark + .section-dark { background: var(--forest-deep); }

/* Coming-soon (honest pre-Stripe state). Same idea as muzikklimax's .coming --
 * a config-driven notice rather than a claim the site can't yet back up. Sits
 * inside the gold-hairline card language already used for .card, not the
 * rounded-panel look muzikklimax uses, so it reads as part of this theme. */
.coming {
  background: #F2F0ED; border: 1px solid var(--gold);
  border-radius: var(--radius); padding: 32px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
}
.coming-note { color: var(--muted); font-size: 15px; max-width: 44ch; margin: 0; }

.section-head { text-align: center; margin-bottom: 64px; }
.rule-gold {
  width: 96px; height: 1px; background: var(--gold);
  margin: 16px auto 0; border: 0;
}

.grid { display: grid; gap: var(--gutter); }
@media (min-width: 768px) {
  .grid-2 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(3, 1fr); }
  .grid-4 { grid-template-columns: repeat(4, 1fr); }
  .grid-12 { grid-template-columns: repeat(12, 1fr); }
}

/* ------------------------------------------------------------- header --- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(249, 248, 246, 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid transparent;
}
.site-header .container {
  display: flex; align-items: center; justify-content: space-between;
  height: 96px; gap: 24px;
}

.wordmark {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-display);
  font-size: 24px; font-weight: 700; color: var(--forest);
  text-decoration: none; white-space: nowrap;
}
/* 34px rather than the 26px that matches the cap height. The mark is an
 * ampersand whose bowl is a six-blade iris, and below roughly 30px those blades
 * collapse into a smudge — the whole point of the mark is lost. Slightly
 * oversized against the wordmark is the better trade. */
.wordmark .mark { width: 34px; height: auto; flex: none; }
.site-footer .wordmark .mark { width: 38px; }

.main-nav { display: none; gap: 32px; align-items: center; }
@media (min-width: 900px) { .main-nav { display: flex; } }

.main-nav a {
  font-size: 12px; font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; text-decoration: none;
  color: var(--obsidian); padding-bottom: 4px;
  border-bottom: 1px solid transparent;
  transition: color 0.3s, border-color 0.3s;
}
.main-nav a:hover { color: var(--gold); }
.main-nav a[aria-current="page"] { color: var(--gold); border-bottom-color: var(--gold); }

.nav-toggle {
  display: inline-flex; background: none; border: 0; padding: 8px;
  color: var(--forest); cursor: pointer;
}
@media (min-width: 900px) { .nav-toggle { display: none; } }

.main-nav.open {
  display: flex; flex-direction: column; align-items: flex-start;
  position: absolute; top: 96px; left: 0; right: 0;
  background: var(--gallery); border-bottom: 1px solid var(--hairline);
  padding: 24px var(--margin-mobile); gap: 20px;
}

/* ------------------------------------------------------------ buttons --- */
.btn {
  display: inline-block; border-radius: var(--radius);
  padding: 18px 40px; border: 1px solid transparent;
  font-family: var(--font-body); font-size: 12px; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none;
  cursor: pointer; transition: background 0.3s, color 0.3s, border-color 0.3s;
}
.btn-primary  { background: var(--forest); color: var(--gallery); }
.btn-primary:hover { background: var(--forest-soft); }

.btn-outline  { background: transparent; color: var(--forest); border-color: var(--forest); }
.btn-outline:hover { background: var(--forest); color: var(--gallery); }

.btn-gold     { background: var(--gold); color: var(--forest); }
.btn-gold:hover { background: var(--gold-light); }

/* On a dark section the outline goes gold, which is the only place gold
 * carries a border at full length. */
.btn-onDark   { background: transparent; color: var(--gold-light); border-color: var(--gold); }
.btn-onDark:hover { background: rgba(197, 160, 89, 0.12); }

.btn-row { display: flex; flex-wrap: wrap; gap: 16px; }
.btn-row.center { justify-content: center; }

/* --------------------------------------------------------------- hero --- */
.hero {
  position: relative; display: flex; align-items: center;
  min-height: 560px; overflow: hidden; background: var(--forest);
}
.hero-tall { min-height: 78vh; }

.hero-media { position: absolute; inset: 0; }
.hero-media img { width: 100%; height: 100%; object-fit: cover; }

/* Forest overlay so display type stays legible over any frame. Two layers,
 * because a single top-to-bottom gradient leaves the vertical middle too light
 * and that is exactly where the lede sits: over a bright sunset exterior the
 * body copy dropped below readable contrast. The radial adds weight through the
 * centre band without darkening the corners of the photograph. */
.hero-media::after {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(
      ellipse 90% 60% at 50% 45%,
      rgba(26, 47, 35, 0.42),
      rgba(26, 47, 35, 0) 70%
    ),
    linear-gradient(
      to bottom,
      rgba(26, 47, 35, 0.34),
      rgba(26, 47, 35, 0.66)
    );
}

.hero-inner { position: relative; z-index: 1; width: 100%; padding: 96px 0; }
.hero h1, .hero p { color: var(--gallery); }
/* Near-white rather than the 72% used on flat dark grounds — over a photograph
 * the extra contrast is what makes the line readable at a glance. */
.hero .lede { color: rgba(249, 248, 246, 0.94); max-width: 40rem; }
.hero-center { text-align: center; }
.hero-center .lede { margin-left: auto; margin-right: auto; }
.hero .label { margin-bottom: 20px; display: block; }
.hero h1 { margin-bottom: 24px; }
.hero .btn-row { margin-top: 40px; }

/* Page banner: shorter hero for interior pages. */
.banner { min-height: 380px; }
@media (min-width: 768px) { .banner { min-height: 460px; } }

/* --------------------------------------------------- matte image frame --- *
 * 16px of white and a hairline, so a photograph on the page reads the way a
 * print reads on a gallery wall. Used anywhere an image is presented as work
 * rather than as decoration. */
.matte {
  padding: 16px; background: #fff;
  border: 1px solid var(--hairline);
  box-shadow: var(--lift);
}
.matte img { width: 100%; }

/* Book page: prose plus an optional sidecar image column (slots 7/18). Single
   column on mobile, same 768px breakpoint the grid-N classes already use, so
   it doesn't need its own responsive logic duplicated. */
.book-layout { display: grid; gap: 48px; }
@media (min-width: 768px) {
  .book-layout { grid-template-columns: 1.6fr 1fr; }
}
.book-sidecar { display: flex; flex-direction: column; gap: 24px; }

.ratio { position: relative; overflow: hidden; }
.ratio > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ratio-16x9 { aspect-ratio: 16 / 9; }
.ratio-16x10 { aspect-ratio: 16 / 10; }
.ratio-4x5  { aspect-ratio: 4 / 5; }
.ratio-1x1  { aspect-ratio: 1 / 1; }
.ratio-3x2  { aspect-ratio: 3 / 2; }

/* --------------------------------------------------------------- cards --- */
.card {
  background: #fff; border: 1px solid var(--hairline);
  border-radius: var(--radius); display: flex; flex-direction: column;
  transition: border-color 0.4s;
}
.card:hover { border-color: var(--gold); }
.card-body { padding: 32px; display: flex; flex-direction: column; flex: 1; }
.card-body h3 { margin-bottom: 8px; }
.card-body p { color: var(--muted); }
.card .price {
  margin-top: auto; padding-top: 16px;
  font-family: var(--font-body); font-size: 12px; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--gold-dark);
}
.card img { transition: transform 0.7s; }
.card:hover img { transform: scale(1.04); }

.card-dark { background: var(--forest); border-color: var(--forest); }
.card-dark h3 { color: var(--gallery); }
.card-dark p  { color: var(--on-dark-soft); }

/* Spec list inside a package or bundle card. Grows to fill so the buy button
 * anchors to the bottom of every card in the row regardless of how many lines
 * each package lists — otherwise the shortest card floats its button halfway up
 * and the row loses its baseline. */
.spec { list-style: none; margin: 0 0 32px; padding: 0; flex: 1; }
.spec li {
  display: flex; gap: 12px; align-items: baseline;
  padding: 10px 0; border-bottom: 1px solid var(--hairline);
  font-size: 16px;
}
.spec li:last-child { border-bottom: 0; }
.spec li::before { content: ""; width: 14px; height: 1px; background: var(--gold); flex: none; transform: translateY(-4px); }
.card-dark .spec li { border-bottom-color: rgba(249, 248, 246, 0.12); }

/* Featured bundle: heavier frame, no gimmicks. */
.card-featured { border: 2px solid var(--forest); position: relative; }
.card-featured .flag {
  position: absolute; top: -1px; left: 50%; transform: translate(-50%, -50%);
  background: var(--forest); color: var(--gallery);
  padding: 6px 16px; font-size: 10px; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; white-space: nowrap;
}

/* ------------------------------------------------------ pricing tables --- *
 * Thin gold dividers instead of a boxed table, so a price list still reads as
 * editorial rather than as a spreadsheet. */
.pricing { width: 100%; border-collapse: collapse; }
.pricing th {
  text-align: left; padding: 0 16px 14px 0;
  font-family: var(--font-body); font-size: 12px; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--forest);
  border-bottom: 1px solid var(--gold);
}
.pricing td {
  padding: 18px 16px 18px 0;
  border-bottom: 1px solid rgba(197, 160, 89, 0.35);
  vertical-align: top;
}
.pricing tr:last-child td { border-bottom: 0; }
.pricing td:last-child, .pricing th:last-child { text-align: right; padding-right: 0; }
.pricing .amount { font-family: var(--font-display); font-size: 20px; color: var(--forest); white-space: nowrap; }
.pricing .name { font-weight: 600; }
.pricing .note { display: block; color: var(--muted); font-size: 14px; margin-top: 4px; }

.table-wrap { overflow-x: auto; }

/* Markdown body content (page.html renders straight Markdown). */
.prose { max-width: 46rem; }
.prose h2 { margin: 48px 0 16px; }
.prose h3 { margin: 32px 0 12px; }
.prose ul { padding-left: 1.1em; }
.prose li { margin-bottom: 8px; }
.prose table { width: 100%; border-collapse: collapse; margin: 24px 0; }
.prose th { text-align: left; border-bottom: 1px solid var(--gold); padding: 0 12px 12px 0; font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; }
.prose td { padding: 14px 12px 14px 0; border-bottom: 1px solid rgba(197, 160, 89, 0.35); }

/* --------------------------------------------------------- tour pages --- */
.tour-frame {
  width: 100%; height: 78vh; min-height: 480px;
  border: 0; display: block; background: var(--forest-deep);
}
.tour-shell-unbranded { background: var(--obsidian); }
.tour-shell-unbranded .tour-frame { height: 100vh; min-height: 0; }

.tour-meta { display: flex; flex-wrap: wrap; gap: 32px; align-items: baseline; }
.tour-meta .address { font-family: var(--font-display); font-size: 24px; color: var(--forest); }

/* Tier rows on the tours page. The divider separates rows, so the last one does
 * not get a line under it with nothing beneath. */
.tier { border-bottom: 1px solid var(--hairline); padding-bottom: 24px; margin-bottom: 24px; }
.tier:last-child { border-bottom: 0; padding-bottom: 0; margin-bottom: 0; }
.tier h3 { display: flex; justify-content: space-between; gap: 16px; align-items: baseline; }
.tier .amount { font-size: 20px; color: var(--gold-dark); white-space: nowrap; }

/* A tour listing tile on the services page. */
.tour-tile { position: relative; display: block; text-decoration: none; overflow: hidden; }
.tour-tile img { transition: transform 0.7s; }
.tour-tile:hover img { transform: scale(1.05); }
.tour-tile .caption {
  position: absolute; left: 24px; bottom: 24px; z-index: 1;
  background: rgba(18, 18, 18, 0.55); color: #fff;
  padding: 6px 12px; font-size: 10px; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
}

/* Empty state for the tour gallery before the first capture exists. Says so
 * plainly rather than showing a stand-in. */
.empty-note {
  border: 1px solid var(--hairline); background: #fff;
  padding: 48px; text-align: center; color: var(--muted);
}

/* ------------------------------------------------------------- process --- */
.step .step-icon {
  width: 48px; height: 48px; display: flex; align-items: center; justify-content: center;
  background: #EDEAE5; color: var(--forest); margin-bottom: 24px;
  transition: background 0.5s, color 0.5s;
}
.step:hover .step-icon { background: var(--forest); color: var(--gallery); }
.step h4 { font-size: 20px; margin-bottom: 12px; }
.step p { color: var(--muted); }

/* -------------------------------------------------------------- footer --- */
.site-footer { background: var(--forest); color: var(--on-dark-soft); padding: 96px 0 0; }
.site-footer .wordmark { color: var(--gallery); }
.site-footer h4 {
  color: var(--gold-light); font-family: var(--font-body);
  font-size: 12px; font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; margin-bottom: 24px;
}
.footer-grid { display: grid; gap: 48px; grid-template-columns: 1fr; }
@media (min-width: 768px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; gap: 64px; } }
.footer-links { display: flex; flex-direction: column; gap: 14px; }
.footer-links a { text-decoration: none; color: var(--on-dark-soft); transition: color 0.3s; }
.footer-links a:hover { color: var(--gold-light); }
.footer-bottom {
  margin-top: 80px; padding: 28px 0;
  border-top: 1px solid rgba(249, 248, 246, 0.1);
  display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between;
  font-size: 12px;
}

/* ------------------------------------------------------------- motion --- *
 * The hidden state is scoped to .js, which an inline script in <head> sets.
 * Without JavaScript the rule never applies and the page renders fully rather
 * than as a column of invisible sections. */
.js .reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.8s ease-out, transform 0.8s ease-out;
}
.js .reveal.visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .card img, .tour-tile img { transition: none; }
  * { scroll-behavior: auto !important; }
}

/* Keyboard focus has to survive a design system this quiet. */
a:focus-visible, button:focus-visible, .btn:focus-visible, input:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

.skip-link {
  position: absolute; left: -9999px;
  background: var(--forest); color: var(--gallery); padding: 12px 20px; z-index: 100;
}
.skip-link:focus { left: 16px; top: 16px; }
