/* ==========================================================================
   Aarth Design — global stylesheet
   Design tokens lifted 1:1 from the live site (aarthdesign.in, "Margarethe"
   WordPress theme) so every page matches it exactly.
   ========================================================================== */

/* --- Fonts ---------------------------------------------------------------
   Cinzel (400/500/600) for headings, logo text, labels and buttons.
   Cormorant Garamond (400/500 + italic) for body copy. Both self-hosted;
   see css/fonts.css, linked before this file.
--------------------------------------------------------------------------- */

:root {
  /* Palette — exact values from the live theme.json */
  --ad-base:      #f3f2ee;   /* page background        */
  --ad-contrast:  #b3563c;   /* Jaipur brick, buttons — same as the Services band.
                                White on it is 4.74:1; it on the cream page is 4.35:1,
                                just under 4.5:1 for small text. Was #ce2d13 until 2026-09-27. */
  --ad-primary:   #3d3d31;   /* body + heading ink     */
  --ad-secondary: #fcfcfa;   /* off-white panels       */
  --ad-ink-60:    rgba(61, 61, 49, 0.62);
  --ad-ink-22:    rgba(61, 61, 49, 0.22);
  --ad-ink-12:    rgba(61, 61, 49, 0.12);
  --ad-ink-06:    rgba(61, 61, 49, 0.06);

  /* Typefaces */
  --font-display: 'Cinzel', Georgia, 'Times New Roman', serif;
  --font-body:    'Cormorant Garamond', Georgia, 'Times New Roman', serif;

  /* Fluid spacing scale (theme presets 20–80) */
  --sp-30: 0.25rem;
  --sp-40: 1rem;
  --sp-50: clamp(1.25rem, 4.19vw, 1.75rem);   /* block gap            */
  --sp-60: clamp(1.75rem, 4.19vw, 3.5rem);    /* page gutter, col gap */
  --sp-70: clamp(3rem, 6.59vw, 5.5rem);       /* band padding         */
  --sp-80: clamp(4.5rem, 10.78vw, 9rem);      /* section rhythm       */

  /* Fluid type scale */
  --fs-x-small:    0.72rem;
  --fs-small:      clamp(0.72rem,  0.72rem  + ((1vw - 0.2rem) * 0.171), 0.9rem);
  --fs-medium:     clamp(0.9rem,   0.9rem   + ((1vw - 0.2rem) * 0.214), 1.125rem);
  --fs-large:      clamp(1.125rem, 1.125rem + ((1vw - 0.2rem) * 0.268), 1.406rem);
  --fs-x-large:    clamp(1.406rem, 1.406rem + ((1vw - 0.2rem) * 0.335), 1.758rem);
  --fs-xx-large:   clamp(2.197rem, 2.197rem + ((1vw - 0.2rem) * 0.524), 2.747rem);
  --fs-xxx-large:  clamp(2.197rem, 2.197rem + ((1vw - 0.2rem) * 1.995), 4.292rem);
  --fs-xxxx-large: clamp(2.747rem, 2.747rem + ((1vw - 0.2rem) * 3.77),  6.706rem);

  /* One multiplier for everything that moved from Cinzel to Cormorant
     Garamond: headings, nav, brand, hero wordmark. Cormorant sets much
     smaller than Cinzel's capitals at the same font-size, so these sizes are
     lifted together from this single value. */
  --type-lift: 1.25;

  /* Measures */
  --content: 620px;
  --wide:    2000px;

  --ease: cubic-bezier(.22, 1, .36, 1);

  /* Fixed nav height, refined by JS (see js/main.js setNavHeight) so
     inner pages can reserve exact space beneath it. This fallback keeps
     layout stable before that JS runs. */
  --nav-h: 6rem;
}

/* --- Reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background-color: var(--ad-base);
  color: var(--ad-primary);
  font-family: var(--font-body);
  font-size: clamp(0.918rem, 0.918rem + ((1vw - 0.2rem) * 0.44), 1.38rem);
  font-weight: 400;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
figure { margin: 0; }
a { color: inherit; text-decoration: none; }
/* Only prose links carry an underline, as on the live site. */
main p a:where(:not(.btn)),
.lede a { text-decoration: underline; text-underline-offset: 0.18em; }
main p a:where(:not(.btn)):hover { text-decoration: none; }
button { font: inherit; color: inherit; }

/* Headings are sentence case, written that way in the HTML and shown as
   written. They use the body face rather than Cinzel because Cinzel has no
   lowercase glyphs: sentence case in Cinzel renders as capitals and small
   capitals, which still reads as all caps. The same applies to the brand,
   the nav and the hero wordmark below. */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-body);
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0.01em;
  line-height: 1.25;
  margin: 0;
}
:where(h1) { font-size: calc(2em * var(--type-lift)); }
:where(h2) { font-size: calc(1.5em * var(--type-lift)); }
:where(h3) { font-size: calc(1.17em * var(--type-lift)); }
:where(h4) { font-size: calc(1em * var(--type-lift)); }
p { margin: 0; letter-spacing: 0.02em; line-height: 1.6; }
p + p { margin-top: 1em; }

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--ad-primary); color: var(--ad-secondary);
  padding: 0.75rem 1rem; z-index: 99;
}
.skip-link:focus { left: 0; }

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

/* --- Layout primitives ---------------------------------------------------- */
.shell { padding-inline: var(--sp-60); }
.wide  { max-width: var(--wide); margin-inline: auto; }
.measure { max-width: var(--content); }

/* Margarethe's signature asymmetric pair: 65.16% + remainder */
.cols {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--sp-50) var(--sp-60);
}
.cols > .col { flex: 1 1 0; min-width: 0; }
.cols > .col--wide   { flex-basis: 65.16%; flex-grow: 0; }
.cols > .col--narrow { flex-basis: 0; flex-grow: 1; }
.cols--halves > .col { flex-basis: calc(50% - (var(--sp-60) / 2)); flex-grow: 0; }

/* Portrait in a narrow column, with the attribution set like a testimonial's.
   The aspect-ratio plus the img's own width/height hold the space before the
   file loads, so nothing under it jumps. */
.portrait { margin: 0; }
.portrait img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 4;
  object-fit: cover;
}
.portrait figcaption {
  margin-top: var(--sp-40);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ad-ink-60);
}
/* Stacked on a phone the full-width portrait would dominate the screen, so it
   takes a readable cap and sits with the text column. */
@media (max-width: 640px) {
  .portrait img { max-width: 18rem; }
}

.section { margin-block: var(--sp-80); }
.band {
  background-color: var(--ad-secondary);
  padding-block: var(--sp-70);
  padding-inline: var(--sp-60);
}
.band h3 { font-family: var(--font-body); font-weight: 500; text-transform: none; letter-spacing: 0; }

/* --- Buttons -------------------------------------------------------------- */
.btn {
  display: inline-block;
  font-family: var(--font-display);
  font-size: var(--fs-medium);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  line-height: 1;
  padding: 1.3rem 1.4rem;
  border: 0;
  border-radius: 0;
  text-decoration: none;
  background-color: var(--ad-contrast);
  color: var(--ad-secondary);
  cursor: pointer;
  transition: background-color .25s var(--ease), color .25s var(--ease);
}
.btn:hover { background-color: var(--ad-primary); color: var(--ad-secondary); }

.btn--outline {
  background-color: transparent;
  color: var(--ad-primary);
  border: 1px solid var(--ad-primary);
}
.btn--outline:hover { background-color: var(--ad-primary); color: var(--ad-secondary); }

.btn--ghost-light {
  background-color: transparent;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, .7);
}
.btn--ghost-light:hover { background-color: #fff; color: var(--ad-primary); }

.cta__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-50); }
.btn--icon { display: inline-flex; align-items: center; gap: .6rem; }
.btn--icon svg { width: 1.1rem; height: 1.1rem; fill: currentColor; flex: none; }

/* The closer's two buttons are one matched pair on every page: same face, same
   real lowercase, same block. The font swap is what makes the casing read at
   all — Cinzel has no lowercase glyphs, so text-transform alone would render
   fake small caps. Height comes from min-height with no block padding, so the
   outline button's 1px border cannot make it the taller of the two, and
   min-width squares both to the wider label. */
.cta__actions .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  min-width: min(15.5rem, 100%);
  min-height: 3.5rem;
  padding-block: 0;
  font-family: var(--font-body);
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0.02em;
}
/* .closer .btn sets a top margin for the project pages' single button. Inside a
   pair that margin lands on both items and doubles up under the paragraph, so
   the pair takes its spacing from the container instead. */
.closer .cta__actions .btn { margin-top: 0; }

/* --- Top bar --------------------------------------------------------------
   Fixed across every page so it stays pinned while scrolling. On the home
   hero it stays fully transparent the whole way down (topbar--over); on
   inner pages it carries the ordinary page background so it reads as a
   solid bar. .topbar--page ~ #main reserves the space it would otherwise
   cover, using the height JS measures into --nav-h. --------------------- */
.topbar {
  position: fixed;
  top: 0;
  inset-inline: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--sp-70);
  padding-block: clamp(0.85rem, 2.6vw, 1.25rem);
  padding-inline: var(--sp-60);
  max-width: var(--wide);
  margin-inline: auto;
  width: 100%;
}
/* Brand hard left, links hard right. .topbar shares the --sp-60 gutter with
   the page body, so the last link lines up with the content edge — and so does
   the hamburger once it replaces the links below 900px. */
.topbar nav { margin-inline-start: auto; }

.topbar--page { background-color: var(--ad-base); }
.topbar--page ~ #main { padding-top: var(--nav-h); }

.brand {
  font-family: var(--font-body);
  font-size: calc(var(--fs-large) * 1.2 * var(--type-lift)); /* 20% under the original 1.5 */
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0.02em;
  line-height: 0.9;
  text-decoration: none;
  margin: 0;
}
.brand a { display: inline-flex; align-items: baseline; gap: .55rem; color: inherit; text-decoration: none; }
.brand__mark { height: calc(var(--fs-large) * 1.8); width: auto; display: block; flex: none; transform: translateY(0.36em); }
.brand__mark--light { display: none; }
.topbar--over .brand__mark--dark { display: none; }
.topbar--over .brand__mark--light { display: block; filter: drop-shadow(0 1px 3px rgba(0,0,0,.85)) drop-shadow(0 0 6px rgba(0,0,0,.5)); }
.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 1;
  gap: var(--sp-50);
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav a {
  font-family: var(--font-body);
  font-size: calc(var(--fs-medium) * var(--type-lift));
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.02em;
  text-decoration: none;
}
.nav a:not(.btn):hover { text-decoration: underline; text-underline-offset: 0.2em; }
.nav a[aria-current="page"]:not(.btn) { text-decoration: underline; text-underline-offset: 0.2em; }

/* Dark-on-image variant used over the home hero. Stays on permanently
   (nav is fixed), so the text carries a shadow for legibility once the
   hero scrolls past and lighter page sections run underneath it. */
.topbar--over { color: #fff; }
.topbar--over .brand,
.topbar--over .nav a { color: #fff; text-shadow: 0 1px 4px rgba(0,0,0,.55), 0 0 10px rgba(0,0,0,.35); }

/* --- Mobile nav toggle + off-canvas drawer --------------------------------- */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: stretch;
  gap: .32rem;
  width: 2.2rem;
  height: 2.2rem;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ad-primary);
  cursor: pointer;
  flex: none;
}
.topbar--over .nav-toggle { color: #fff; filter: drop-shadow(0 1px 3px rgba(0,0,0,.55)); }
.nav-toggle__bar { display: block; height: 2px; background: currentColor; border-radius: 1px; }

.nav-scrim {
  position: fixed;
  inset: 0;
  z-index: 95;
  background: rgba(0, 0, 0, .45);
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s var(--ease);
}
body.nav-open .nav-scrim { opacity: 1; pointer-events: auto; }
body.nav-open { overflow: hidden; }

/* --- Home hero ------------------------------------------------------------ */
.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
  padding-inline: var(--sp-60);
  isolation: isolate;
  color: #fff;
}
.hero__media,
.hero__scrim { position: absolute; inset: 0; z-index: -1; }
.hero__media { width: 100%; height: 100%; object-fit: cover; object-position: center 17%; }
.hero__scrim {
  background-image:
    linear-gradient(to right, rgba(0,0,0,.44) 0%, rgba(0,0,0,.24) 40%, rgba(0,0,0,0) 68%),
    linear-gradient(rgba(0,0,0,.26) 0%, rgba(0,0,0,0) 42%, rgba(0,0,0,.46) 96%);
}
.hero__body {
  flex: 1;
  display: flex;
  align-items: flex-end;
  width: 100%;
  max-width: var(--wide);
  margin-inline: auto;
  padding-block: var(--sp-70);
}
.hero__body .cols { width: 100%; }
.hero h1 {
  font-family: var(--font-body);
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--fs-xxxx-large);
  line-height: 1.0011;
  color: #fff;
  text-shadow: 0 2px 10px rgba(0,0,0,.6), 0 1px 30px rgba(0,0,0,.4);
}

/* --- Page header (inner pages) -------------------------------------------- */
.page-head { margin-block: clamp(1.68rem, 3.6904vw, 3.08rem) var(--sp-60); }
.page-head h1 { font-size: calc(var(--fs-xxx-large) * var(--type-lift)); line-height: 1.05; }
.lede { max-width: 46ch; margin-top: var(--sp-50); }
/* Projects page quote and its attribution, a step above body text. */
.page-head blockquote.lede { font-size: 1.15em; }

.eyebrow {
  display: flex;
  align-items: center;
  gap: .75rem;
  font-family: var(--font-display);
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ad-ink-60);
  margin-bottom: var(--sp-50);
}
.eyebrow::before {
  content: "";
  width: 2.25rem;
  height: 1px;
  background: var(--ad-ink-22);
  flex: none;
}

.crumbs {
  font-family: var(--font-display);
  font-size: var(--fs-x-small);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ad-ink-60);
  padding-block: var(--sp-50) 0;
}
.crumbs a { text-decoration: none; }
.crumbs a:hover { text-decoration: underline; }
.crumbs span { margin-inline: .5rem; }

/* --- Process grid (home) -------------------------------------------------- */
.process h3 { font-family: var(--font-body); font-size: var(--fs-xxx-large); font-weight: 500; line-height: 1.05; text-transform: none; letter-spacing: 0; }
/* Photo beside four one-line steps. Each step is a <details>: the short line
   stays visible and a click opens the full description, one step at a time
   (details[name], with a fallback in main.js). The last step, Build, carries
   the brand red (number and a heavier rule) as a quiet finish line.
   Side by side, the photo is cropped to the height of the text column, so
   "How we work" lines up with its top edge and Build's red line with its
   bottom edge; opening a step grows both together. */
.process__wrap {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-60);
  align-items: stretch;
}
@media (min-width: 761px) {
  .process__media { position: relative; display: flex; flex-direction: column; }
  .process__frame { position: relative; flex: 1; min-height: 320px; }
  .process__media .process__frame img { position: absolute; inset: 0; height: 100%; aspect-ratio: auto; }
  /* Hangs below the photo so the photo edge, not the caption, meets the red line. */
  .process__media figcaption { position: absolute; top: 100%; left: 0; }
}
.process__media { margin: 0; }
.process__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: 2px;
  display: block;
}
.process__media figcaption { margin-top: .5rem; font-size: var(--fs-small); color: var(--ad-ink-60); }
.process__media figcaption a { color: inherit; }
.process__list { list-style: none; margin: var(--sp-50) 0 0; padding: 0; }
.process__list li { border-top: 1px solid var(--ad-ink-12); }
.process__list summary {
  display: grid;
  grid-template-columns: 2.25rem 1fr 1.25rem;
  gap: .75rem;
  padding: .9rem 0;
  cursor: pointer;
  list-style: none;
}
.process__list summary::-webkit-details-marker { display: none; }
.process__list summary:focus-visible { outline: 2px solid var(--ad-primary); outline-offset: 2px; }
.process__list summary:hover h4 { text-decoration: underline; text-underline-offset: .2em; text-decoration-thickness: 1px; }
/* Plus that turns into a minus. */
.process__toggle { position: relative; width: 12px; height: 12px; margin-top: .5rem; justify-self: end; }
.process__toggle::before,
.process__toggle::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 1px;
  background: var(--ad-primary);
  transition: transform .3s var(--ease);
}
.process__toggle::after { transform: rotate(90deg); }
.process__list details[open] .process__toggle::after { transform: rotate(0deg); }
.process__more {
  color: var(--ad-ink-60);
  padding: 0 2rem 1rem 3rem;
  animation: process-in .35s var(--ease);
}
@keyframes process-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .process__more { animation: none; }
  .process__toggle::after { transition: none; }
}
.process__list li:last-child { border-bottom: 2px solid var(--ad-contrast); }
.process__num { font-family: var(--font-display); font-size: var(--fs-small); color: var(--ad-ink-60); padding-top: .3rem; }
.process__list li:last-child .process__num { color: var(--ad-contrast); }
.process__list h4 {
  font-family: var(--font-body);
  font-size: calc(var(--fs-medium) * var(--type-lift));
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.15;
}
.process__list p { color: var(--ad-ink-60); }
@media (max-width: 760px) {
  .process__wrap { grid-template-columns: 1fr; }
  .process__media img { aspect-ratio: 3 / 2; }
}

/* --- Services band (home + services) ---------------------------------------
   A deep Jaipur brick: the one section that breaks from the light palette, so
   it reads as its own moment. The tone is set by the text — white needs 4.5:1
   for the small numerals, which this clears at 4.74:1. Any lighter and the
   band drifts toward pink city, where white stops being legible. ----------- */
.services {
  position: relative;
  overflow: hidden;
  background-color: #b3563c;
  color: var(--ad-secondary);
  padding-block: var(--sp-80);
}
/* Two soft, off-axis glows plus a fine diagonal hatch — texture without
   competing with the type. Decorative only. */
.services::before,
.services::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.services::before {
  background:
    radial-gradient(60% 50% at 12% -10%, rgba(255,255,255,.07), transparent 60%),
    radial-gradient(55% 60% at 105% 115%, rgba(61,61,49,.14), transparent 60%);
}
.services::after {
  background-image: repeating-linear-gradient(
    135deg, rgba(255,255,255,.035) 0 1px, transparent 1px 10px
  );
  mix-blend-mode: overlay;
}
.services > .wide { position: relative; }.services h1,
.services h3 { color: var(--ad-secondary); font-size: calc(var(--fs-xxx-large) * var(--type-lift)); line-height: 1.05; }

.services__grid {
  list-style: none;
  margin: var(--sp-60) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-60) var(--sp-50);
}
@media (min-width: 720px) { .services__grid { grid-template-columns: repeat(3, 1fr); } }
.services__item {
  padding-top: var(--sp-50);
  border-top: 1px solid rgba(252, 252, 250, 0.3);
}
.services__num {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-small);
  letter-spacing: 0.1em;
  color: var(--ad-secondary);
  margin-bottom: var(--sp-40);
  font-variant-numeric: tabular-nums;
}
.services__item h4 {
  font-family: var(--font-body);
  font-size: calc(var(--fs-medium) * var(--type-lift));
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.15;
  color: var(--ad-secondary);
}

/* Scroll-triggered reveal, used by the services band above. Gated behind
   html.js (set synchronously in <head> on pages that use this, before first
   paint, so there's no flash of hidden content) and only ever active when
   the visitor hasn't asked for reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  html.js .rv {
    opacity: 0;
    transform: translateY(18px);
  }
  html.js .rv.in {
    opacity: 1;
    transform: none;
    transition: opacity .8s var(--ease), transform .8s var(--ease);
  }
  html.js .rv.in[data-delay="1"] { transition-delay: .08s; }
  html.js .rv.in[data-delay="2"] { transition-delay: .16s; }
  html.js .rv.in[data-delay="3"] { transition-delay: .24s; }
  html.js .rv.in[data-delay="4"] { transition-delay: .32s; }
  html.js .rv.in[data-delay="5"] { transition-delay: .4s; }
}

/* --- Footer --------------------------------------------------------------- */
.site-footer {
  padding-block: var(--sp-70);
  padding-inline: var(--sp-60);
  border-top: 1px solid var(--ad-ink-12);
}
.site-footer .brand { font-size: calc(var(--fs-x-large) * var(--type-lift)); line-height: 0.9; }
.footer__stack { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-50); }
.socials { display: flex; gap: 1rem; list-style: none; margin: 0; padding: 0; }
.socials a { display: block; flex: none; line-height: 0; text-decoration: none; opacity: .85; }
.socials svg { flex: none; }
.socials a:hover { opacity: 1; }
.socials svg { width: 18px; height: 18px; fill: currentColor; }
.footer__detail {
  font-family: var(--font-body);
  font-size: var(--fs-large);
  font-weight: 400;
  line-height: 1.3;
}
.footer__detail a { text-decoration: none; }
.footer__detail a:hover { text-decoration: underline; }
.footer__fine {
  margin-top: var(--sp-80);
  font-size: var(--fs-x-small);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ad-ink-60);
}

/* ==========================================================================
   PROJECTS PAGE
   Layout copied from aarthdesign.vercel.app/projects (eyebrow, filter pills,
   three-column masonry, triptych cards, name/category meta bar) and re-skinned
   in the aarthdesign.in palette and typefaces.
   ========================================================================== */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: var(--sp-60);
  padding: 0;
  border: 0;
}
.filter {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  height: 2.5rem;
  padding-inline: 1rem;
  background: transparent;
  border: 1px solid var(--ad-ink-22);
  border-radius: 2px;
  color: var(--ad-ink-60);
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color .16s var(--ease), border-color .16s var(--ease), background-color .16s var(--ease);
}
.filter:hover { color: var(--ad-primary); border-color: rgba(61, 61, 49, .45); }
.filter[aria-pressed="true"] {
  background: var(--ad-primary);
  border-color: var(--ad-primary);
  color: var(--ad-secondary);
}
.filter__n { font-variant-numeric: tabular-nums; opacity: .7; letter-spacing: .06em; }

.count {
  margin-top: var(--sp-50);
  font-size: var(--fs-small);
  letter-spacing: 0.04em;
  color: var(--ad-ink-60);
}

.mosaic {
  margin-top: var(--sp-60);
  columns: 1;
  column-gap: 1.25rem;
}
@media (min-width: 640px)  { .mosaic { columns: 2; } }
@media (min-width: 1024px) { .mosaic { columns: 3; column-gap: 1.5rem; } }

.mosaic-block {
  break-inside: avoid;
  margin-bottom: 1.25rem;
  padding: .75rem;
  background: var(--ad-secondary);
  border: 1px solid var(--ad-ink-12);
  border-radius: 2px;
  transition: border-color .25s var(--ease);
}
@media (min-width: 1024px) { .mosaic-block { margin-bottom: 1.5rem; padding: 1rem; } }
.mosaic-block:hover { border-color: var(--ad-ink-22); }

.mosaic-block > a { display: block; text-decoration: none; }
.stack { display: flex; flex-direction: column; gap: .625rem; }
.shot {
  overflow: hidden;
  border-radius: 2px;
  background: var(--ad-ink-06);
}
.shot img {
  width: 100%;
  transition: transform .42s var(--ease);
}
.mosaic-block a:hover .shot img { transform: scale(1.03); }

.meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: .25rem 1rem;
  margin-top: .75rem;
}
.meta__name {
  font-family: var(--font-display);
  font-size: var(--fs-medium);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.meta__right { display: flex; align-items: baseline; gap: .625rem; }
.meta__cat { font-size: var(--fs-small); color: var(--ad-ink-60); letter-spacing: .02em; }
.tag-viz {
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ad-contrast);
  border: 1px solid currentColor;
  border-radius: 2px;
  padding: .15rem .4rem;
  white-space: nowrap;
}

.empty {
  margin-top: var(--sp-60);
  color: var(--ad-ink-60);
}

/* --- Closing CTA (projects / contact) ------------------------------------- */
.closer { margin-top: var(--sp-80); }
.closer h2 { font-family: var(--font-body); font-size: var(--fs-xxx-large); font-weight: 500; line-height: 1.05; text-transform: none; letter-spacing: 0; }
.closer p  { margin-top: var(--sp-50); }
.closer .btn { margin-top: var(--sp-60); }

/* --- Contact ---------------------------------------------------------------
   Form controls deliberately don't inherit --font-body (Playfair Display,
   a display serif) — legible input text on a static form wants a plain
   system sans, so it's declared once here rather than through a token. --- */
.contact-layout { margin-top: var(--sp-70); }

.contact-form__title { font-size: calc(var(--fs-xx-large) * var(--type-lift)); margin-bottom: var(--sp-60); }

.contact-form__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-50);
}
.contact-form__row + .contact-form__row,
.contact-form__row + .field,
.contact-form > .field + .contact-form__row,
.contact-form > .field + .field {
  margin-top: var(--sp-50);
}

.field { display: flex; flex-direction: column; gap: .6rem; }
.field label {
  font-family: var(--font-display);
  font-size: var(--fs-small);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.field__req { color: var(--ad-contrast); margin-left: .2em; }

.field input,
.field select,
.field textarea {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-size: var(--fs-medium);
  color: var(--ad-primary);
  background: var(--ad-secondary);
  border: 1px solid var(--ad-ink-22);
  border-radius: 0;
  padding: .85rem 1rem;
  width: 100%;
}
.field input::placeholder,
.field textarea::placeholder { color: var(--ad-ink-60); opacity: 1; }
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: 2px solid var(--ad-contrast);
  outline-offset: 1px;
}
.field textarea { resize: vertical; min-height: 8rem; font-family: inherit; }
.field select { cursor: pointer; }

.contact-form__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-50);
  margin-top: var(--sp-60);
}
.contact-form__hint {
  margin-top: var(--sp-40);
  font-family: var(--font-body);
  font-size: var(--fs-small);
  color: var(--ad-ink-60);
}

.contact-side > .eyebrow { margin-top: calc(var(--fs-xx-large) * 1.2 - var(--fs-small) * 1.6); margin-bottom: var(--sp-60); }
.contact-detail { display: flex; gap: 1rem; align-items: flex-start; }
.contact-detail + .contact-detail { margin-top: var(--sp-60); }
.contact-detail__icon {
  flex: none;
  width: 1.35rem;
  height: 1.35rem;
  margin-top: .2rem;
  color: var(--ad-ink-60);
}
.contact-detail__icon svg { width: 100%; height: 100%; fill: currentColor; }
.contact-detail h3 {
  font-size: calc(var(--fs-large) * var(--type-lift));
  margin-bottom: .35rem;
}
.contact-detail p {
  font-family: var(--font-body);
  font-size: 1em; /* same size as body text; headings unchanged */
  color: var(--ad-ink-60);
}
.contact-detail p + p { margin-top: .35rem; color: var(--ad-primary); font-weight: 600; }
.contact-detail p + p a { color: inherit; }

@media (max-width: 700px) {
  .contact-form__row { grid-template-columns: 1fr; }
}

/* --- Responsive ----------------------------------------------------------- */
@media (max-width: 781px) {
  .cols { display: block; }
  .cols > .col + .col { margin-top: var(--sp-50); }
  .cols > .col--wide, .cols--halves > .col { flex-basis: auto; }
  .cols > .col[aria-hidden="true"] { display: none; }
  .contact-side > .eyebrow { margin-top: 0; }

  .btn { padding: 1rem 1.15rem; }
  .site-footer .brand { font-size: calc(1.5rem * var(--type-lift)); }
  .footer__fine { margin-top: var(--sp-70); }
}

/* Header alone breaks earlier (900px) than the rest of the layout (781px):
   at desktop sizes the nav links + full-size logo stop fitting one row
   well before other two-column layouts need to stack. Without its own
   breakpoint, that gap let "AARTH DESIGN" wrap to two lines, which broke
   the icon/text baseline alignment (the flex row then sized to the taller
   two-line box). */
@media (max-width: 900px) {
  .topbar .brand { font-size: calc(1.68rem * var(--type-lift)); line-height: 1; }
  .topbar .brand__mark { height: 2.52rem; }
  .nav-toggle { display: flex; }

  /* Off-canvas drawer, slides in from the right. */
  .nav {
    position: fixed;
    top: 0;
    right: 0;
    z-index: 100;
    width: min(80vw, 320px);
    height: 100vh;
    height: 100dvh;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: var(--sp-50);
    background: var(--ad-secondary);
    padding: calc(var(--nav-h) + var(--sp-50)) var(--sp-60) var(--sp-60);
    transform: translateX(100%);
    transition: transform .35s var(--ease);
    overflow-y: auto;
  }
  #primary-nav a { color: var(--ad-primary); text-shadow: none; font-size: calc(1.15rem * var(--type-lift)); }
  /* Outranks the #primary-nav a colour above, which otherwise leaves the
     button's text the same dark olive as its own hover background. */
  #primary-nav .btn { color: var(--ad-secondary); }
  .nav .btn { font-size: calc(1.05rem * var(--type-lift)); padding: .8rem 1rem; white-space: nowrap; margin-top: var(--sp-40); }
  body.nav-open .nav { transform: translateX(0); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* ===========================================================================
   HOMEPAGE — depth layout
   ---------------------------------------------------------------------------
   Only index.html carries body.immersive, so every rule below is inert on the
   other pages. The effect is depth, not decoration: content sits on raised
   slabs, the first slab overlaps the hero so the page reads as layers rather
   than one sheet, and motion stays limited to the existing .rv reveal.

   Bar, page, slabs and CTA band all share --ad-base. Nothing shows a colour
   seam where the fixed bar meets the content; separation comes from shadow
   and a hairline border instead of a lighter fill.
   ======================================================================== */
.immersive {
  --slab-radius: 4px;
  --slab-pad: clamp(1.5rem, 3.4vw, 3.25rem);
  --slab-lift: clamp(1rem, 3.5vw, 3rem);
  --slab-shadow:
    0 1px 1px rgba(61, 61, 49, .03),
    0 6px 16px rgba(61, 61, 49, .05),
    0 20px 48px rgba(61, 61, 49, .06);
  --slab-shadow-deep:
    0 2px 4px rgba(61, 61, 49, .05),
    0 12px 28px rgba(61, 61, 49, .08),
    0 36px 80px rgba(61, 61, 49, .09);
}

.immersive .slab {
  position: relative;
  background-color: var(--ad-base);
  border: 1px solid var(--ad-ink-06);
  border-radius: var(--slab-radius);
  padding: var(--slab-pad);
  box-shadow: var(--slab-shadow);
}

/* The overlap is what sells the layering — without it the slabs read as
   plain cards. The hero gains matching bottom room so the panel that rides
   over it does not crowd the heading. */
.immersive .section--lift {
  margin-top: calc(-1 * var(--slab-lift));
  z-index: 2;
}
.immersive .section--lift .slab { box-shadow: var(--slab-shadow-deep); }
.immersive .hero__body { padding-bottom: calc(var(--sp-70) + var(--slab-lift) / 2); }

.immersive .services,
.immersive .band {
  margin-inline: var(--sp-60);
  border-radius: var(--slab-radius);
  box-shadow: var(--slab-shadow-deep);
}
.immersive .services { overflow: hidden; }
.immersive .band {
  background-color: var(--ad-base);
  border: 1px solid var(--ad-ink-06);
  margin-block: var(--sp-80);
}

/* .topbar--over keeps its links white for the photo behind them, but the bar
   is fixed, so once the hero scrolls away that white sits on the cream page
   and disappears. main.js flags the crossing with .topbar-solid, and adds
   .topbar-line only while a section is actually under the bar — a permanent
   rule would float in the gaps with nothing to divide. */
.immersive .topbar {
  transition: background-color .3s var(--ease), box-shadow .3s var(--ease);
}
.immersive.topbar-solid .topbar { background-color: var(--ad-base); }
.immersive.topbar-line .topbar { box-shadow: 0 1px 0 var(--ad-ink-12); }
.immersive.topbar-solid .topbar--over .brand,
.immersive.topbar-solid .topbar--over .nav a {
  color: var(--ad-primary);
  text-shadow: none;
}
.immersive.topbar-solid .topbar--over .nav-toggle {
  color: var(--ad-primary);
  filter: none;
}
/* The CTA keeps its rust fill, so its own text stays light. */
.immersive.topbar-solid .topbar--over .nav a.btn { color: var(--ad-secondary); }

/* The bar must sit above everything. .hero sets isolation:isolate, which makes
   it a stacking context and traps the bar's z-index inside it, so later
   sections paint over the bar. Dropping the isolation frees the bar to compete
   at the root, where its z-index:100 wins. The hero's own layers then need
   explicit order, since they relied on that context: the photo and scrim stop
   using z-index:-1, and the body is lifted above them instead. */
.immersive .hero { isolation: auto; }
.immersive .hero__media,
.immersive .hero__scrim { z-index: auto; }
.immersive .hero__body { position: relative; z-index: 1; }

/* Slow push-in on the home photo, like walking up the path to the door. The
   picture clips the zoom so the photo never spills past the hero. The zoom is
   centred on the wall band the wordmark sits on (same maths as the wordmark
   offset below), so the wordmark stays on that wall while the arches and door
   grow around it. It runs once and holds; reduced motion gets a still. */
.immersive .hero > picture { position: absolute; inset: 0; overflow: hidden; }
.immersive .hero__media {
  transform-origin: 50% calc(50% - 2.95svh);
  animation: hero-walk 30s cubic-bezier(.37, 0, .63, 1) both;
  will-change: transform;
}
@media (min-aspect-ratio: 3/2) {
  .immersive .hero__media { transform-origin: 50% calc(50% + 20vw - 33svh); }
}
@keyframes hero-walk {
  from { transform: scale(1); }
  to   { transform: scale(1.1); }
}
@media (prefers-reduced-motion: reduce) {
  .immersive .hero__media { animation: none; }
}

/* Hero carries the wordmark alone, centred on both axes. */
.immersive .hero__body {
  align-items: center;
  justify-content: center;
  text-align: center;
  /* Symmetric again: the extra bottom room above was for a heading sitting low
     in the frame, and it pushes a centred wordmark off the middle. */
  padding-block: var(--sp-70);
}
.immersive .hero__wordmark {
  margin: 0;
  font-weight: 500;
  letter-spacing: 0.02em;
  font-size: calc(var(--fs-xxxx-large) * var(--type-lift));
  line-height: 1.05;
}
/* Centre the wordmark on the plain wall between the arch tops and the door
   head, which runs from 42.5% to 51.6% of the photo's height (middle 47.05%).
   Where it sits on screen depends on how object-fit crops the 3:2 photo:
   - Screens narrower than 3:2 fit the photo to the hero's height, so the band
     middle is 47.05% of the height: 2.95svh above centre.
   - Wider screens fit it to the width (photo height 0.6665 x width) and trim
     the excess at object-position 17%, which puts the band middle at
     0.17 x height + 0.2003 x width, i.e. (20vw - 33svh) from centre. */
/* Always two lines, "Aarth" over "Design", on every screen width. The space
   between the spans keeps the heading's text reading "Aarth Design". */
.hero__line { display: block; }
.immersive .hero__wordmark { transform: translateY(-2.95svh); }
@media (min-aspect-ratio: 3/2) {
  .immersive .hero__wordmark { transform: translateY(calc(20vw - 33svh)); }
}

/* Sentence case on a single button (the intro's "Our projects"); other
   buttons keep the uppercase display face. Body face for real lowercase. */
.btn--sentence {
  font-family: var(--font-body);
  font-size: calc(var(--fs-medium) * var(--type-lift));
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0.02em;
}

/* Only one wordmark shows at a time: the bar's brand fades out while the hero
   is on screen, and returns once .topbar-solid says the hero has passed. */
.immersive .topbar .brand {
  transition: opacity .3s var(--ease);
}
.immersive:not(.topbar-solid) .topbar .brand {
  opacity: 0;
  pointer-events: none;
}

/* --- Testimonials ---------------------------------------------------------
   A row of cards you swipe sideways, using native scroll snapping rather than
   a scripted slider, so touch, trackpad, keyboard and scrollbar all work
   without our help. Both cards fit at desktop width, at which point there is
   nothing to scroll; the row only becomes swipeable once they no longer fit. */
.quotes { margin-top: var(--sp-60); }
.quotes__stage {
  display: flex;
  gap: var(--sp-50);
  overflow-x: auto;
  /* Proximity, not mandatory: a card is one gap wider than the scroll range
     can quite reach, and mandatory snapping treats that 1px shortfall as
     "closest snap point is the first card" and springs back, stranding the
     last card off screen. Proximity still snaps on a real swipe. */
  scroll-snap-type: x proximity;
  scroll-behavior: smooth;
  padding-bottom: var(--sp-40);
  overscroll-behavior-x: contain;
}
.quotes__item {
  /* 82%, not 100%: the edge of the next card stays in view on a phone, which
     is the only thing that tells a reader there is a second card to swipe to.
     At desktop width 26rem wins and both cards sit side by side as before. */
  flex: 0 0 min(82%, 26rem);
  scroll-snap-align: start;
  background-color: var(--ad-secondary);
  border: 1px solid var(--ad-ink-06);
  border-radius: 4px;
  padding: var(--sp-50);
}
.quotes__body { margin: 0; }
.quotes__body p { margin: 0 0 var(--sp-40); }
.quotes__body p:last-child { margin-bottom: 0; }
.quotes__more {
  margin-top: var(--sp-40);
  padding: 0;
  background: none;
  border: 0;
  font-family: var(--font-display);
  font-size: var(--fs-small);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ad-primary);
  text-decoration: underline;
  text-underline-offset: 0.3em;
  cursor: pointer;
}
.quotes__more:hover { text-decoration: none; }
.quotes__by {
  margin: var(--sp-50) 0 0;
  font-family: var(--font-display);
  font-size: var(--fs-small);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ad-ink-60);
}
@media (prefers-reduced-motion: reduce) {
  .quotes__stage { scroll-behavior: auto; }
}

/* Flat and full width on purpose. It anchors the page so everything above it
   reads as floating. */
.immersive .site-footer { margin-top: var(--sp-80); }

@media (max-width: 781px) {
  .immersive .services,
  .immersive .band { margin-inline: var(--sp-50); }
}

/* Social block belongs to the slide-out drawer only. The desktop bar is a thin
   horizontal strip with no room for a heading. */
.nav__socials { display: none; }

@media (max-width: 900px) {
  .nav__socials {
    display: block;
    /* .nav sets align-items:flex-start, so this item would shrink to its own
       content and hug the left. Stretching it gives text-align something to
       centre against. */
    align-self: stretch;
    margin-top: auto;
    padding-top: var(--sp-50);
    border-top: 1px solid var(--ad-ink-12);
    text-align: center;
  }
  .nav__socials-title {
    margin: 0 0 var(--sp-40);
    font-family: var(--font-display);
    font-size: var(--fs-small);
    font-weight: 500;
    letter-spacing: 0.1em;
    color: var(--ad-primary);
  }
  .nav__socials .socials { gap: var(--sp-50); justify-content: center; }

  /* Drawer is sized by its links; height stays full screen. Same drawer on
     every page, not just the home page. */
  #primary-nav {
    width: max-content;
    box-shadow: var(--slab-shadow-deep);
  }
  /* The drawer is a later sibling at the same z-index, so it would cover the
     button. Lifting the button keeps the three lines visible and clickable,
     as though the panel opened underneath it. */
  .nav-toggle { position: relative; z-index: 101; }
  .immersive.nav-open .topbar--over .nav-toggle {
    color: var(--ad-primary);
    filter: none;
  }
}
