/* ==========================================================================
   Nubuilt - components
   ========================================================================== */

/* ---- Buttons ------------------------------------------------------------
   Rounded but not playful. The fill sweeps from the bottom edge, which is
   the same directional language as the image reveals.                      */

.btn {
  --btn-bg:     var(--graphite);
  --btn-fg:     var(--paper);
  --btn-sweep:  var(--blue);

  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  padding: 0.95em 1.6em;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: 0.01em;
  color: var(--btn-fg);
  background: var(--btn-bg);
  border: var(--border) solid var(--btn-bg);
  border-radius: var(--radius);
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: color var(--dur-base) var(--ease-out-arch);
}

.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--btn-sweep);
  transform: translateY(100%);
  transition: transform var(--dur-base) var(--ease-out-arch);
  z-index: -1;
}

.btn:hover::before,
.btn:focus-visible::before { transform: translateY(0); }

.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--graphite);
  border-color: var(--graphite);
}
.btn--ghost:hover, .btn--ghost:focus-visible { color: var(--paper); }

.btn--stone { --btn-bg: var(--stone); --btn-fg: var(--graphite); --btn-sweep: var(--stone-dark); }
.btn--blue  { --btn-bg: var(--blue);  --btn-fg: #fff; --btn-sweep: var(--graphite); }

.btn--large { font-size: var(--step-0); padding: 1.05em 2em; }

/* ---- Cards --------------------------------------------------------------
   Minimal shadows, thin borders, large images - per the brand brief.       */

.card {
  display: flex;
  flex-direction: column;
  background: var(--paper-pure);
  border: var(--border) solid var(--hairline);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition:
    transform  var(--dur-base) var(--ease-out-arch),
    box-shadow var(--dur-base) var(--ease-out-arch),
    border-color var(--dur-base) var(--ease-out-arch);
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
  border-color: var(--stone);
}

/* Home house-plans band: a single focused column, not a card grid. */
.plans-band__text { max-width: 56ch; }
.plans-band__list {
  color: var(--grey);
  font-size: var(--step-0);
  padding-top: var(--space-2xs);
}

.card__media { aspect-ratio: 4 / 5; background: var(--paper-shade); }
.card__media img { width: 100%; height: 100%; object-fit: cover; }

/* A responsive image comes wrapped in <picture>, which the base reset leaves
   at height:auto. The img's height:100% then resolves against that auto
   height and collapses, so the image falls back to its own intrinsic ratio
   (a 1600x1000 cover showing as a 16:10 box inside a 4:5 slot on a portrait
   screen). Making the wrapper fill the box lets height:100% resolve, so the
   box's aspect-ratio governs and object-fit does the cropping. */
.card__media picture,
.hero__media picture,
.cs-hero__media picture,
.plan-hero__media picture,
.gallery__item picture { display: block; width: 100%; height: 100%; }
.card__body { padding: var(--space-m); display: flex; flex-direction: column; gap: var(--space-2xs); flex: 1; }
.card__title { font-size: var(--step-2); }
.card__text { font-size: var(--step--1); color: var(--grey); }
.card__foot { margin-top: auto; padding-top: var(--space-s); font-size: var(--step--1); font-weight: var(--weight-medium); color: var(--graphite); display: flex; align-items: center; gap: var(--space-3xs); }

.card--media-3-2 .card__media { aspect-ratio: 3 / 2; }
.card--media-16-10 .card__media { aspect-ratio: 16 / 10; }

/* ---- Stat block ---------------------------------------------------------
   Proof, not decoration. Answers "can a small company handle this?"        */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: var(--space-l);
  border-top: 1px solid var(--hairline);
  padding-top: var(--space-l);
}

.stat__figure {
  font-family: var(--font-display);
  font-size: var(--step-5);
  line-height: 1;
  letter-spacing: var(--tracking-display);
  color: var(--graphite);
  font-variant-numeric: tabular-nums;
}

.stat__label {
  font-size: var(--step--1);
  color: var(--grey);
  margin-top: var(--space-2xs);
}

/* ---- Header -------------------------------------------------------------- */

.header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid transparent;
}

.header.is-condensed {
  border-bottom-color: var(--hairline);
  box-shadow: 0 1px 24px rgba(28,28,28,0.05);
}

.header__inner {
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
}

.header.is-condensed .header__inner { height: var(--header-h-condensed); }

.header__logo { display: flex; align-items: center; gap: var(--space-2xs); }
.header__logo svg, .header__logo img { height: 2.25rem; width: auto; }

.header__wordmark {
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-weight: var(--weight-semi);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--graphite);
}

.nav { display: flex; align-items: center; gap: var(--space-l); }

.nav__link {
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  color: var(--graphite);
  position: relative;
  padding-block: var(--space-2xs);
}

.nav__link::after {
  content: "";
  position: absolute;
  inset-inline-start: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--graphite);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-base) var(--ease-out-arch);
}
.nav__link:hover::after, .nav__link[aria-current="page"]::after { transform: scaleX(1); }

/* ---- Language switcher --------------------------------------------------- */

.lang {
  display: flex;
  align-items: center;
  gap: var(--space-3xs);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
}

.lang__item {
  padding: var(--space-3xs) var(--space-2xs);
  border-radius: 2px;
  color: var(--grey);
  transition: color var(--dur-fast) var(--ease-soft), background-color var(--dur-fast) var(--ease-soft);
}
.lang__item:hover { color: var(--graphite); }
.lang__item[aria-current="true"] { color: var(--graphite); background: var(--stone-light); }

/* ---- Mobile menu --------------------------------------------------------- */

.menu-toggle { display: none; background: none; border: 0; padding: var(--space-2xs); cursor: pointer; }

.menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-menu);
  background: var(--graphite);
  color: var(--paper);
  padding: var(--gutter);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-m);
}

.menu[hidden] { display: none; }
.menu__link { font-family: var(--font-display); font-size: var(--step-4); color: var(--paper); }

@media (max-width: 60rem) {
  .nav--primary { display: none; }
  .menu-toggle { display: block; }

  /* The language switcher and Contact button move into the slide-out menu on
     mobile, so the top bar holds only the logo and the toggle. Without this
     they collide with the toggle on a narrow phone. */
  .header__actions > .lang,
  .header__actions > .btn--ghost { display: none; }
}

/* The switcher inside the mobile menu sits at the foot, on the dark panel. */
.menu__foot { margin-top: var(--space-l); }
.menu__foot .lang__item { color: rgba(245, 243, 239, 0.7); }
.menu__foot .lang__item:hover { color: var(--paper); }
.menu__foot .lang__item[aria-current="true"] { color: var(--paper); background: rgba(245, 243, 239, 0.12); }

/* ---- WhatsApp ------------------------------------------------------------
   In this market more prospects message than fill in a form. Treated as a
   primary action, not a widget.                                            */

.whatsapp {
  position: fixed;
  inset-inline-end: var(--space-m);
  bottom: var(--space-m);
  z-index: var(--z-toast);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  padding: 0.85em 1.25em;
  background: var(--graphite);
  color: var(--paper);
  border-radius: 100px;
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  box-shadow: var(--shadow-lift);
  transition: transform var(--dur-base) var(--ease-out-arch), background-color var(--dur-base) var(--ease-out-arch);
}
.whatsapp:hover { transform: translateY(-3px); background: var(--blue); }

@media (max-width: 40rem) {
  .whatsapp span { display: none; }
  .whatsapp { padding: 0.9em; }
}

/* ---- Footer -------------------------------------------------------------- */

.footer {
  background: var(--graphite);
  color: #A5A19A;
  padding-block: var(--space-2xl) var(--space-l);
}

.footer a { color: var(--paper); }
.footer h2, .footer h3 { color: var(--paper); }

.footer__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--space-xl);
}

.footer__bottom {
  margin-top: var(--space-xl);
  padding-top: var(--space-m);
  border-top: 1px solid var(--hairline-invert);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
  justify-content: space-between;
  font-size: var(--step--2);
}

/* ---- Hero ---------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: min(88vh, 54rem);
  display: grid;
  align-items: end;
  padding-block: var(--space-2xl);
}

.hero .hero__media {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--graphite);
}

.hero__media img { width: 100%; height: 100%; object-fit: cover; }

/* A real scrim rather than a flat image opacity: darker at the foot where the
   heading and buttons sit, lighter at the top so the image still reads. This
   is what carries the white text, so it is deliberately strong. */
.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,
              rgba(12,12,12,0.86) 0%,
              rgba(12,12,12,0.60) 45%,
              rgba(12,12,12,0.40) 100%);
}

.hero__content { position: relative; color: var(--paper); }
.hero .display, .hero .eyebrow { color: var(--paper); }
.hero .lead { color: rgba(245,243,239,0.82); }

/* ---- The difference statement ------------------------------------------- */

.difference__line {
  font-family: var(--font-display);
  font-size: var(--step-3);
  line-height: 1.25;
  letter-spacing: var(--tracking-heading);
  color: var(--grey-light);
  padding-block: var(--space-s);
  border-bottom: 1px solid var(--hairline);
}

.difference__line--us {
  color: var(--graphite);
  font-size: var(--step-2);
  line-height: 1.4;
  border-bottom: 0;
  max-width: 54ch;
  padding-top: var(--space-l);
}

/* ---- Placeholder --------------------------------------------------------- */

.placeholder {
  display: grid;
  place-items: center;
  background:
    repeating-linear-gradient(45deg, var(--paper-shade) 0 10px, var(--paper) 10px 20px);
  color: var(--grey);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  text-align: center;
  padding: var(--space-s);
  border: 1px dashed var(--hairline);
}

/* ---- Homepage sections (Phase 1) ---------------------------------------- */

/* Journey cards: three equal paths, side by side, stacking on mobile. */
.journeys {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-m);
}

@media (max-width: 52rem) {
  .journeys { grid-template-columns: 1fr; max-width: 30rem; }
}

/* Section head: a title on the left, a lead paragraph on the right. */
.work__head,
.pricing__head {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-xl);
  align-items: end;
}

.work__head .lead,
.pricing__head .lead { max-width: 40ch; }

@media (max-width: 52rem) {
  .work__head,
  .pricing__head { grid-template-columns: 1fr; gap: var(--space-m); align-items: start; }
}

.work__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-m);
}

@media (max-width: 60rem) { .work__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 40rem) { .work__grid { grid-template-columns: 1fr; max-width: 26rem; } }

/* Why: four points in a row of numbered blocks. */
.why__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-l);
}

@media (max-width: 60rem) { .why__grid { grid-template-columns: 1fr 1fr; gap: var(--space-xl) var(--space-l); } }
@media (max-width: 36rem) { .why__grid { grid-template-columns: 1fr; } }

.why__point { display: flex; flex-direction: column; gap: var(--space-2xs); }

.why__num {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--stone-dark);
  letter-spacing: var(--tracking-eyebrow);
  padding-bottom: var(--space-xs);
  border-bottom: 1px solid var(--hairline);
  margin-bottom: var(--space-2xs);
}

.why__title { font-size: var(--step-1); }
.why__text { font-size: var(--step--1); color: var(--grey); }

/* Pricing snapshot: four figures, then a note and a link. */
.pricing__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-m);
}

@media (max-width: 56rem) { .pricing__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 30rem) { .pricing__grid { grid-template-columns: 1fr; } }

.price {
  padding: var(--space-m);
  background: var(--paper-pure);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  transition: border-color var(--dur-base) var(--ease-out-arch),
              transform var(--dur-base) var(--ease-out-arch);
}

.price:hover { border-color: var(--stone); transform: translateY(-3px); }

.price__label { font-size: var(--step--1); color: var(--grey); }

.price__from {
  font-family: var(--font-display);
  font-size: var(--step-2);
  color: var(--graphite);
  letter-spacing: var(--tracking-heading);
  margin-top: var(--space-3xs);
}

.pricing__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
}

.price__note { font-size: var(--step--1); color: var(--grey); margin: 0; }

/* ==========================================================================
   Showcase (Phase 2)
   The portfolio, category indexes and case studies. Built on the same tokens
   and the .card base above, so a project looks native everywhere it appears.
   ========================================================================== */

/* ---- Project grid -------------------------------------------------------- */
.project-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr));
  gap: var(--space-l);
}

.project-grid--related { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 60rem) { .project-grid--related { grid-template-columns: 1fr 1fr; } }
@media (max-width: 40rem) { .project-grid--related { grid-template-columns: 1fr; max-width: 26rem; } }

/* ---- Project card -------------------------------------------------------- */
.project-card { position: relative; text-decoration: none; color: inherit; }
.project-card .card__media { position: relative; }

.project-card__meta {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--stone-dark);
}

.project-card__badge {
  position: absolute;
  top: var(--space-2xs);
  inset-inline-start: var(--space-2xs);
  z-index: 1;
  padding: 0.25em 0.7em;
  background: var(--blue);
  color: #fff;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 100px;
}

/* Dark variant: the featured strip on the homepage and the related strip. */
.project-card--dark {
  background: #232323;
  border-color: var(--hairline-invert);
}
.project-card--dark:hover { border-color: var(--stone); }
.project-card--dark .card__text { color: #A5A19A; }
.project-card--dark .card__foot { color: var(--paper); }
.project-card--dark .project-card__meta { color: var(--stone); }

/* ---- Breadcrumbs --------------------------------------------------------- */
.crumbs__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs);
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: var(--step--1);
  color: var(--grey);
}
.crumbs__item { display: inline-flex; align-items: center; gap: var(--space-2xs); }
.crumbs__item a { color: var(--grey); }
.crumbs__item [aria-current="page"] { color: var(--graphite); }
.crumbs__sep { color: var(--stone-dark); flex: none; }
.is-dark .crumbs__list, .cs-hero .crumbs__list { color: rgba(245,243,239,0.7); }
.is-dark .crumbs__item a, .cs-hero .crumbs__item a { color: rgba(245,243,239,0.7); }
.is-dark .crumbs__item [aria-current="page"], .cs-hero .crumbs__item [aria-current="page"] { color: var(--paper); }

/* ---- Index head ---------------------------------------------------------- */
.index-head { max-width: 52rem; }
.index-head .lead { max-width: 46ch; }

/* ---- Filter bar ---------------------------------------------------------- */
.filter { display: flex; flex-wrap: wrap; gap: var(--space-2xs); }

.filter__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  padding: 0.55em 1em;
  border: 1px solid var(--hairline);
  border-radius: 100px;
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  color: var(--graphite);
  background: var(--paper-pure);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-soft),
              background-color var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft);
}
.filter__chip:hover { border-color: var(--stone); }
.filter__chip.is-active { background: var(--graphite); border-color: var(--graphite); color: var(--paper); }
.filter__chip.is-empty { opacity: 0.5; }

.filter__count {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--grey);
}
.filter__chip.is-active .filter__count { color: rgba(245,243,239,0.7); }

.filter__empty { padding: var(--space-2xl) 0; text-align: center; color: var(--grey); }

/* ---- Case study: hero ---------------------------------------------------- */
.cs-hero {
  position: relative;
  display: grid;
  align-items: end;
  min-height: min(78vh, 46rem);
  padding-block: var(--space-2xl);
  overflow: hidden;
  background: var(--graphite-900);
  isolation: isolate;
}
.cs-hero .cs-hero__media { position: absolute; inset: 0; z-index: -2; }
.cs-hero__media img { width: 100%; height: 100%; object-fit: cover; }
.cs-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top,
              rgba(18,18,18,0.94) 0%,
              rgba(18,18,18,0.68) 40%,
              rgba(18,18,18,0.44) 100%);
}
.cs-hero__inner { position: relative; color: var(--paper); }
.cs-hero__content { margin-top: var(--space-l); max-width: 60rem; }
.cs-hero .display { color: var(--paper); }
.cs-hero .lead { color: rgba(245,243,239,0.85); }
.cs-hero__badge { position: static; display: inline-block; }

/* ---- Case study: body ---------------------------------------------------- */
.cs-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 18rem;
  gap: var(--space-2xl);
  align-items: start;
}
@media (max-width: 56rem) {
  .cs-body { grid-template-columns: 1fr; gap: var(--space-xl); }
}
.cs-body__main { max-width: 60ch; }

.cs-block__text {
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--graphite);
  margin-top: var(--space-s);
}

.cs-facts {
  position: sticky;
  top: calc(var(--header-h) + var(--space-m));
  padding: var(--space-l);
  background: var(--paper-pure);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
}
@media (max-width: 56rem) { .cs-facts { position: static; } }

.facts { margin: 0; display: grid; gap: var(--space-m); }
.facts__row dt {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--stone-dark);
}
.facts__row dd { margin: var(--space-3xs) 0 0; color: var(--graphite); font-weight: var(--weight-medium); }

/* ---- Tags ---------------------------------------------------------------- */
.tags { display: flex; flex-wrap: wrap; gap: var(--space-2xs); list-style: none; padding: 0; margin: 0; }
.tag {
  padding: 0.3em 0.85em;
  border: 1px solid currentColor;
  border-radius: 100px;
  font-size: var(--step--1);
  opacity: 0.85;
}
.cs-hero .tag { color: var(--stone); }

/* ---- Gallery ------------------------------------------------------------- */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr));
  gap: var(--space-m);
}
.gallery--wide { grid-template-columns: repeat(auto-fill, minmax(min(100%, 28rem), 1fr)); }

.gallery__item {
  display: block;
  padding: 0;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--paper-shade);
  cursor: zoom-in;
  aspect-ratio: 3 / 2;
}
.gallery__item img { width: 100%; height: 100%; object-fit: cover; }

/* ---- Video facade -------------------------------------------------------- */
.video-facade {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: #000;
}
.video-facade__btn {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.video-facade__thumb { width: 100%; height: 100%; object-fit: cover; opacity: 0.82; transition: opacity var(--dur-base) var(--ease-out-arch); }
.video-facade__btn:hover .video-facade__thumb { opacity: 1; }
.video-facade__play {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  width: 5rem; height: 5rem;
  padding-left: 0.35rem; /* optical centring of a triangle that never mirrors */
  border-radius: 100px;
  background: var(--blue);
  color: #fff;
  box-shadow: var(--shadow-lift);
  transition: transform var(--dur-base) var(--ease-out-arch);
}
.video-facade__btn:hover .video-facade__play { transform: translate(-50%, -50%) scale(1.08); }
.video-facade iframe { width: 100%; height: 100%; border: 0; display: block; }

/* ---- Downloads (plans and documents) ------------------------------------ */
.downloads { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 22rem), 1fr)); gap: var(--space-m); }
.download {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  padding: var(--space-s);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--paper-pure);
  color: var(--graphite);
  transition: border-color var(--dur-base) var(--ease-out-arch), transform var(--dur-base) var(--ease-out-arch);
}
.download:hover { border-color: var(--stone); transform: translateY(-2px); }
.download__preview {
  flex: none;
  width: 3.25rem; height: 3.25rem;
  display: grid;
  place-items: center;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--paper-shade);
}
.download__preview img { width: 100%; height: 100%; object-fit: cover; }
.download__ext { font-family: var(--font-mono); font-size: var(--step--2); color: var(--stone-dark); font-weight: var(--weight-semi); }
.download__meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.download__name { font-weight: var(--weight-medium); word-break: break-word; }
.download__size { font-family: var(--font-mono); font-size: var(--step--2); color: var(--grey); }
.download__icon { flex: none; color: var(--stone-dark); }

/* ---- Testimonial quote --------------------------------------------------- */
.quote { margin: 0; }
.quote__text {
  font-family: var(--font-display);
  font-size: var(--step-3);
  line-height: 1.4;
  letter-spacing: var(--tracking-heading);
  color: var(--graphite);
}
.quote__text::before { content: "\201C"; }
.quote__text::after { content: "\201D"; }
.quote__by { margin-top: var(--space-m); font-size: var(--step--1); color: var(--grey); }
.quote__role { color: var(--stone-dark); }

/* ---- Empty state --------------------------------------------------------- */
.showcase-empty {
  max-width: 40rem;
  margin: 0 auto;
  padding: var(--space-2xl) 0;
  text-align: center;
}
.showcase-empty__text { font-size: var(--step-1); color: var(--grey); margin-top: var(--space-s); }

/* ---- Lightbox (built by showcase.js) ------------------------------------ */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-menu);
  display: grid;
  grid-template-rows: 1fr auto;
  place-items: center;
  padding: var(--space-l);
  background: rgba(16,16,16,0.94);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-out-arch),
              visibility 0s linear var(--dur-base);
}
.lightbox.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity var(--dur-base) var(--ease-out-arch);
}
.lightbox__img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: var(--radius);
}
.lightbox__caption { color: rgba(245,243,239,0.75); font-size: var(--step--1); margin-top: var(--space-s); font-family: var(--font-mono); }
.lightbox__close {
  position: absolute;
  top: var(--space-m); inset-inline-end: var(--space-m);
  width: 3rem; height: 3rem;
  display: grid; place-items: center;
  background: rgba(245,243,239,0.12);
  color: var(--paper);
  border: 0; border-radius: 100px;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.lightbox__close:hover { background: rgba(245,243,239,0.24); }
.lightbox__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 3rem; height: 3rem;
  display: grid; place-items: center;
  background: rgba(245,243,239,0.12);
  color: var(--paper);
  border: 0; border-radius: 100px;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.lightbox__nav:hover { background: rgba(245,243,239,0.24); }
.lightbox__nav--prev { inset-inline-start: var(--space-m); }
.lightbox__nav--next { inset-inline-end: var(--space-m); }
@media (max-width: 40rem) {
  .lightbox__nav { top: auto; bottom: var(--space-m); transform: none; }
  .lightbox__nav--prev { inset-inline-start: var(--space-m); }
  .lightbox__nav--next { inset-inline-end: var(--space-m); }
}

/* ==========================================================================
   Phase 3 - forms, panels, notices, FAQ
   Every value below comes from tokens.css. Nothing here invents one.
   ========================================================================== */

/* ---- Contact layout -----------------------------------------------------
   Single column on a phone, with the form first: the aside is reference
   material, and nobody scrolls past an address block to reach a form.       */

.contact-layout {
  display: grid;
  gap: var(--space-xl);
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 64rem) {
  .contact-layout {
    grid-template-columns: minmax(0, 1fr) 21rem;
    gap: var(--space-2xl);
    align-items: start;
  }
}

.contact-aside {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

/* ---- WhatsApp invitation ------------------------------------------------
   Above the form, not beside it. In this market it out-converts the form,
   so it gets the first position rather than a polite sidebar mention.       */

.wa-invite {
  background: var(--paper-pure);
  border: var(--border) solid var(--hairline);
  border-inline-start: 3px solid var(--blue);
  border-radius: var(--radius-lg);
  padding: var(--space-m);
  margin-bottom: var(--space-xl);
}

.wa-invite__title { font-size: var(--step-1); letter-spacing: var(--tracking-heading); }
.wa-invite__body {
  color: var(--grey);
  font-size: var(--step--1);
  line-height: var(--lh-body);
  margin: var(--space-2xs) 0 var(--space-m);
  max-width: var(--measure);
}

/* ---- Form ---------------------------------------------------------------- */

.form-heading { font-size: var(--step-2); letter-spacing: var(--tracking-heading); }
.form-intro {
  color: var(--grey);
  font-size: var(--step--1);
  margin: var(--space-2xs) 0 var(--space-l);
}

.form__row { margin-bottom: var(--space-m); }

.form__row--split {
  display: grid;
  gap: var(--space-m);
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 40rem) {
  .form__row--split { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Honeypot. Off-screen rather than display:none, which some bots skip. */
.form__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.field { display: flex; flex-direction: column; gap: var(--space-3xs); }

.field__label {
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  color: var(--graphite);
  display: flex;
  align-items: baseline;
  gap: var(--space-2xs);
}

.field__optional {
  font-size: var(--step--2);
  font-weight: var(--weight-regular);
  color: var(--grey-light);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
}

.field__input {
  width: 100%;
  padding: 0.75em 0.9em;
  background: var(--paper-pure);
  color: var(--graphite);
  border: var(--border) solid var(--hairline);
  border-radius: var(--radius);
  font-size: var(--step-0);
  line-height: var(--lh-snug);
  transition:
    border-color var(--dur-fast) var(--ease-soft),
    box-shadow   var(--dur-fast) var(--ease-soft);
}

.field__input::placeholder { color: var(--grey-light); }

.field__input:hover { border-color: var(--stone-dark); }

.field__input:focus-visible {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(0, 102, 255, 0.16);
}

.field__input--area { resize: vertical; min-height: 8rem; line-height: var(--lh-body); }

/* Native select, restyled rather than replaced: a custom dropdown here would
   cost keyboard support and mobile ergonomics for nothing. */
.field__input--select {
  appearance: none;
  -webkit-appearance: none;
  padding-inline-end: 2.5em;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position:
    calc(100% - 1.15em) calc(50% + 1px),
    calc(100% - 0.8em)  calc(50% + 1px);
  background-size: 0.36em 0.36em, 0.36em 0.36em;
  background-repeat: no-repeat;
}

.field__help {
  font-size: var(--step--2);
  color: var(--grey);
  line-height: var(--lh-snug);
}

.field__error {
  font-size: var(--step--2);
  color: var(--alert);
  font-weight: var(--weight-medium);
  line-height: var(--lh-snug);
}

.field--error .field__input { border-color: var(--alert); }
.field--error .field__input:focus-visible {
  box-shadow: 0 0 0 3px rgba(163, 42, 33, 0.16);
}

.form__foot {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  align-items: flex-start;
  margin-top: var(--space-l);
}

.form__consent {
  font-size: var(--step--2);
  color: var(--grey);
  line-height: var(--lh-snug);
  max-width: 44ch;
}

/* ---- Notices -------------------------------------------------------------
   Three states, and the middle one earns its keep: 'saved' is what the page
   shows when the enquiry is on disk but the mail did not go out. Telling the
   visitor the truth there is the whole point of writing to disk first.      */

.notice {
  border: var(--border) solid var(--hairline);
  border-inline-start: 3px solid var(--grey);
  border-radius: var(--radius-lg);
  padding: var(--space-m);
  background: var(--paper-pure);
}

.notice__title { font-size: var(--step-1); letter-spacing: var(--tracking-heading); }
.notice__body {
  color: var(--grey);
  line-height: var(--lh-body);
  margin-top: var(--space-2xs);
  max-width: var(--measure);
}
.notice__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  margin-top: var(--space-m);
}
.notice__list { margin: var(--space-2xs) 0 0; padding-inline-start: var(--space-m); }
.notice__list li { margin-top: var(--space-3xs); }
.notice__list a { color: var(--alert); }

.notice--good { border-inline-start-color: var(--ok);    background: var(--ok-tint); }
.notice--warn { border-inline-start-color: var(--warn);  background: var(--warn-tint); }
.notice--bad  { border-inline-start-color: var(--alert); background: var(--alert-tint); margin-bottom: var(--space-l); }

.notice--good .notice__title { color: var(--ok); }
.notice--warn .notice__title { color: var(--warn); }
.notice--bad  .notice__title { color: var(--alert); }

/* ---- Aside panels -------------------------------------------------------- */

.panel {
  background: var(--paper-pure);
  border: var(--border) solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-m);
}

.panel--quiet { background: transparent; }

.panel__title {
  font-size: var(--step-0);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--grey);
  font-weight: var(--weight-medium);
}

.panel__address {
  font-style: normal;
  margin-top: var(--space-s);
  line-height: var(--lh-snug);
}

.panel__list { margin-top: var(--space-s); }
.panel__list dt {
  font-size: var(--step--2);
  color: var(--grey);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  margin-top: var(--space-s);
}
.panel__list dt:first-child { margin-top: 0; }
.panel__list dd { margin: var(--space-3xs) 0 0; line-height: var(--lh-snug); }
.panel__list dd a { word-break: break-word; }

.panel__foot { margin-top: var(--space-m); font-size: var(--step--1); }

/* ---- Tick list ----------------------------------------------------------- */

.ticks { list-style: none; margin-top: var(--space-s); padding: 0; }

.ticks li {
  position: relative;
  padding-inline-start: var(--space-m);
  margin-top: var(--space-s);
  font-size: var(--step--1);
  line-height: var(--lh-snug);
  color: var(--grey);
}

.ticks li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 0.42em;
  width: 0.5rem;
  height: 0.28rem;
  border-inline-start: 1.5px solid var(--blue);
  border-bottom: 1.5px solid var(--blue);
  transform: rotate(-45deg);
}

/* ---- FAQ ----------------------------------------------------------------
   Open prose rather than an accordion. Three questions do not need hiding,
   and collapsed text is worth less to a search engine than visible text.    */

.faq { margin-top: var(--space-l); }

.faq__item {
  padding-top: var(--space-m);
  margin-top: var(--space-m);
  border-top: var(--border) solid var(--hairline);
}

.faq__item:first-child { margin-top: 0; }

.faq__q { font-size: var(--step-1); letter-spacing: var(--tracking-heading); }
.faq__a {
  color: var(--grey);
  line-height: var(--lh-body);
  margin-top: var(--space-2xs);
  max-width: var(--measure);
}

/* ---- Stone accent band --------------------------------------------------- */

.section--stone { background: var(--stone-light); }

/* ---- Inline arrow link --------------------------------------------------- */

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  font-weight: var(--weight-medium);
}

/* ==========================================================================
   Phase 3 - service hubs and service pages
   ========================================================================== */

.svc-grid {
  display: grid;
  gap: var(--space-m);
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 44rem) { .svc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 76rem) { .svc-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.svc-card { text-decoration: none; color: inherit; }
.svc-card .card__body { gap: var(--space-xs); }

.svc-card__price {
  font-family: var(--font-display);
  font-size: var(--step-1);
  letter-spacing: var(--tracking-heading);
  color: var(--graphite);
}

/* ---- Prose ---------------------------------------------------------------
   Body copy on a service page. Measure-limited: these pages run long and an
   unconstrained line is the fastest way to make 1,000 words unreadable.     */

.prose > * + * { margin-top: var(--space-m); }
.prose p { max-width: var(--measure); line-height: var(--lh-body); color: var(--grey); }
.prose h2 { font-size: var(--step-3); letter-spacing: var(--tracking-heading); color: var(--graphite); }
.prose h3 { font-size: var(--step-1); letter-spacing: var(--tracking-heading); color: var(--graphite); }
.prose h3 + p { margin-top: var(--space-2xs); }
.prose > div + div { margin-top: var(--space-l); }

/* ---- Numbered process ---------------------------------------------------
   Numbered because this content genuinely is a sequence. Each step only
   makes sense after the one before it, so the numbers carry information.    */

.steps { list-style: none; padding: 0; margin-top: var(--space-l); counter-reset: step; }

.steps__item {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr);
  gap: var(--space-m);
  padding-top: var(--space-m);
  margin-top: var(--space-m);
  border-top: var(--border) solid var(--hairline);
}

.steps__item:first-child { margin-top: 0; }

.steps__n {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--stone-dark);
  padding-top: 0.2em;
}

.steps__title { font-size: var(--step-1); letter-spacing: var(--tracking-heading); }
.steps__body {
  color: var(--grey);
  line-height: var(--lh-body);
  margin-top: var(--space-3xs);
  max-width: var(--measure);
}

/* ---- Price list ---------------------------------------------------------
   A definition list, not a table: it is a set of terms and their prices,
   and it collapses honestly on a phone where a table would not.            */

.pricelist { margin-top: var(--space-l); }

.pricelist__row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-s);
  padding: var(--space-m) 0;
  border-top: var(--border) solid var(--hairline);
}

.pricelist__row:last-child { border-bottom: var(--border) solid var(--hairline); }

.pricelist dt {
  font-size: var(--step-1);
  font-family: var(--font-display);
  letter-spacing: var(--tracking-heading);
  color: var(--graphite);
  flex: 1 1 14rem;
}

.pricelist__scope {
  display: block;
  font-family: var(--font-body);
  font-size: var(--step--1);
  letter-spacing: var(--tracking-body);
  color: var(--grey);
  font-weight: var(--weight-regular);
  margin-top: var(--space-3xs);
  max-width: 44ch;
}

.pricelist dd {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--step-2);
  letter-spacing: var(--tracking-heading);
  color: var(--graphite);
  white-space: nowrap;
}

.pricelist__note {
  margin-top: var(--space-m);
  font-size: var(--step--1);
  color: var(--grey);
  max-width: var(--measure);
}

/* Wider tick list for the long "what is included" runs. */
.ticks--wide { margin-top: var(--space-l); }
.ticks--wide li { font-size: var(--step-0); max-width: var(--measure); }

/* ---- Support plans ------------------------------------------------------
   Their own component rather than the pricelist: two prices each, a
   recommended tier, and a feature list. Annual is the large number and
   monthly sits under it in body weight, never hidden and never styled as
   the lesser choice.                                                       */

.plans {
  display: grid;
  gap: var(--space-m);
  grid-template-columns: minmax(0, 1fr);
  margin-top: var(--space-l);
}

@media (min-width: 56rem) { .plans { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.plan {
  background: var(--paper-pure);
  border: var(--border) solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-m);
  display: flex;
  flex-direction: column;
}

/* The recommended tier is marked by weight and a rule, not by colour alone. */
.plan--pick {
  border-color: var(--graphite);
  box-shadow: var(--shadow-card);
}

.plan__flag {
  font-size: var(--step--2);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--blue-text);
  font-weight: var(--weight-medium);
  margin-bottom: var(--space-2xs);
}

.plan__name { font-size: var(--step-2); letter-spacing: var(--tracking-heading); }

.plan__for {
  color: var(--grey);
  font-size: var(--step--1);
  line-height: var(--lh-snug);
  margin-top: var(--space-3xs);
}

.plan__price {
  font-family: var(--font-display);
  font-size: var(--step-4);
  letter-spacing: var(--tracking-display);
  line-height: var(--lh-tight);
  margin-top: var(--space-m);
  display: flex;
  align-items: baseline;
  gap: var(--space-2xs);
  flex-wrap: wrap;
}

.plan__per {
  font-family: var(--font-body);
  font-size: var(--step--1);
  letter-spacing: var(--tracking-body);
  color: var(--grey);
}

.plan__month {
  font-size: var(--step-0);
  color: var(--grey);
  margin-top: var(--space-3xs);
}

.plan__features {
  margin-top: var(--space-m);
  padding-top: var(--space-m);
  border-top: var(--border) solid var(--hairline);
}

.plan__features li { margin-top: var(--space-xs); }

/* ---- Journey step links -------------------------------------------------
   A step that has a product attached links to it and shows its price. The
   price is pulled from the service's own translation key, so the two can
   never drift apart.                                                       */

.steps__link { margin-top: var(--space-s); font-size: var(--step--1); }

.steps__price {
  font-family: var(--font-display);
  color: var(--grey);
  margin-inline-start: var(--space-3xs);
}

/* ---- Legal documents ----------------------------------------------------
   Reference material, read once and rarely. Numbered headings would imply a
   contract clause structure the copy does not have, so it stays as prose.  */

.legal__updated {
  margin-top: var(--space-m);
  font-size: var(--step--1);
  color: var(--grey-light);
}

.legal > div + div { margin-top: var(--space-xl); }
.legal h2 { font-size: var(--step-2); }

/* A payment moment inside a process step. Marked, because "when do I pay" is
   the question people are actually scanning for. */
.steps__money {
  margin-top: var(--space-2xs);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  color: var(--blue-text);
}

/* ---- Pricing page -------------------------------------------------------
   Two small components, both introduced by /pricing in Phase 4.

   The jump nav exists because this is the longest document on the site and a
   visitor arrives with one discipline in mind. Plain anchors, no JavaScript,
   so it works before the page has finished loading and it is a real list of
   links to a keyboard and a screen reader.                                  */

.jumpnav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-xs);
  padding-top: var(--space-m);
  border-top: var(--border) solid var(--hairline);
}

.jumpnav__link {
  display: inline-block;
  padding: var(--space-3xs) var(--space-xs);
  border: var(--border) solid var(--hairline);
  border-radius: var(--radius);
  font-size: var(--step--1);
  letter-spacing: var(--tracking-body);
  color: var(--grey);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft),
              background-color var(--dur-fast) var(--ease-soft);
}

.jumpnav__link:hover,
.jumpnav__link:focus-visible {
  color: var(--graphite);
  border-color: var(--stone-dark);
  background: var(--stone-light);
}

/* On a phone these are thumbed, not clicked. At the base padding they measured
   about 32px tall, under the 44px target size, so the padding grows rather
   than the type. Measured at 48px after this rule. */
@media (max-width: 48rem) {
  .jumpnav__link { padding: var(--space-xs) var(--space-s); }
}

/* Anchored sections must not land under the sticky header. */
[id="architecture"],
[id="digital"],
[id="bundle"],
[id="support"],
[id="addons"],
[id="terms"] { scroll-margin-top: var(--space-xl); }

/* One service inside a discipline. The rule above each block does the
   separating, so the blocks need no card treatment: this page is a reference
   document and boxing every service would make it look like a shop.         */

.price-block + .price-block { margin-top: var(--space-2xl); }

.price-block h3 {
  font-size: var(--step-2);
  padding-top: var(--space-m);
  border-top: var(--border) solid var(--stone);
}

.price-block .pricelist__note { margin-top: var(--space-2xs); }
.price-block .steps__link { margin-top: var(--space-m); }

/* ---- House plan library (Phase 5) ---------------------------------------
   Touch targets: every chip and control here is at least 48px tall on a
   phone. Phase 4 shipped 32px targets that only a programmatic audit caught,
   so the padding below is measured rather than eyeballed.                  */

.plan-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr));
  gap: var(--space-l);
}

.plan-card { position: relative; text-decoration: none; color: inherit; }
.plan-card .card__media { position: relative; }
.plan-card__media { aspect-ratio: 3 / 2; }

.plan-card__meta {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--stone-dark);
}

.plan-card__price {
  display: flex;
  align-items: baseline;
  gap: var(--space-2xs);
  margin-top: var(--space-s);
  padding-top: var(--space-s);
  border-top: var(--border) solid var(--hairline);
}
.plan-card__price-label {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--grey);
}
.plan-card__price-value {
  font-size: var(--step-1);
  font-weight: var(--weight-semi);
  letter-spacing: var(--tracking-heading);
}

/* ---- The filter ---------------------------------------------------------- */

.plan-filter {
  display: grid;
  gap: var(--space-m);
  padding: var(--space-m);
  border: var(--border) solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--paper-pure);
}
.plan-filter__group { border: 0; padding: 0; margin: 0; min-width: 0; }
.plan-filter__legend {
  display: block;
  padding: 0;
  margin-bottom: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--grey);
}
.plan-filter__chips { display: flex; flex-wrap: wrap; gap: var(--space-2xs); }

.plan-filter__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  min-height: 48px;
  padding: 0.55em 1em;
  border: 1px solid var(--hairline);
  border-radius: 100px;
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  color: var(--graphite);
  background: var(--paper-pure);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-soft),
              background-color var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft);
}
.plan-filter__chip:hover { border-color: var(--stone); }
.plan-filter__chip.is-active { background: var(--graphite); border-color: var(--graphite); color: var(--paper); }
.plan-filter__chip.is-empty { opacity: 0.45; cursor: not-allowed; }

/* The radio itself is the accessible control; the label is the visible chip.
   Clipped rather than display:none so it stays focusable and announced. */
.plan-filter__chip input {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}
.plan-filter__chip:focus-within { outline: 2px solid var(--blue); outline-offset: 2px; }

.plan-filter__count {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--grey);
}
.plan-filter__chip.is-active .plan-filter__count { color: rgba(245,243,239,0.7); }

.plan-filter__stand { display: flex; align-items: center; gap: var(--space-2xs); }
.plan-filter__input {
  min-height: 48px;
  width: 9rem;
  padding: 0 var(--space-s);
  border: var(--border) solid var(--hairline);
  border-radius: var(--radius);
  font: inherit;
  color: var(--graphite);
  background: var(--paper-pure);
}
.plan-filter__input:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.plan-filter__unit { font-family: var(--font-mono); font-size: var(--step--1); color: var(--grey); }
.plan-filter__help {
  margin-top: var(--space-2xs);
  font-size: var(--step--1);
  color: var(--grey);
  max-width: var(--measure);
}

.plan-filter__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s);
  padding-top: var(--space-s);
  border-top: var(--border) solid var(--hairline);
}
.plan-filter__showing {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--grey);
}

@media (min-width: 60rem) {
  .plan-filter { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .plan-filter__group--stand { grid-column: 1 / -1; }
  .plan-filter__actions { grid-column: 1 / -1; }
}

/* ---- Plan detail --------------------------------------------------------- */

.plan-hero { display: grid; gap: var(--space-xl); align-items: start; }
@media (min-width: 60rem) {
  .plan-hero { grid-template-columns: 1.1fr 1fr; gap: var(--space-2xl); }
}
.plan-hero__media {
  position: relative;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--stone-light);
}
.plan-hero__media img { width: 100%; height: 100%; object-fit: cover; }

.plan-price {
  margin-top: var(--space-l);
  padding: var(--space-m);
  border: var(--border) solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--paper-pure);
}
.plan-price__label {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--grey);
}
.plan-price__value {
  font-size: var(--step-4);
  font-weight: var(--weight-semi);
  letter-spacing: var(--tracking-display);
  line-height: var(--lh-tight);
  margin-top: var(--space-3xs);
}
.plan-price__note {
  margin-top: var(--space-2xs);
  font-size: var(--step--1);
  color: var(--grey);
  max-width: var(--measure);
}

/* ---- Spec table ---------------------------------------------------------- */

.spec { margin-top: var(--space-m); }
.spec__row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-s);
  padding: var(--space-s) 0;
  border-bottom: var(--border) solid var(--hairline);
}
.spec__key { color: var(--grey); }
.spec__value { margin: 0; font-weight: var(--weight-medium); }

/* ---- Indicative build cost ----------------------------------------------
   Styled as one block on purpose. The figure and its qualifier are a single
   unit of meaning and must not be separable by a stylesheet change.        */

.build-cost {
  padding: var(--space-m);
  border: var(--border) solid var(--hairline);
  border-inline-start: 3px solid var(--stone-dark);
  border-radius: var(--radius-lg);
  background: var(--paper-shade);
}
.build-cost__label {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--grey);
}
.build-cost__value {
  font-size: var(--step-3);
  font-weight: var(--weight-semi);
  letter-spacing: var(--tracking-display);
  line-height: var(--lh-tight);
  margin-top: var(--space-3xs);
}
.build-cost__qualifier {
  margin-top: var(--space-2xs);
  font-size: var(--step--1);
  line-height: var(--lh-body);
  color: var(--graphite);
  max-width: var(--measure);
}
.build-cost__more { margin-top: var(--space-s); }
.build-cost__more summary {
  min-height: 44px;
  display: flex;
  align-items: center;
  cursor: pointer;
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  color: var(--blue-text);
}
.build-cost__more p {
  margin-top: var(--space-2xs);
  font-size: var(--step--1);
  color: var(--grey);
  max-width: var(--measure);
}

/* ---- Currency control (header) ------------------------------------------
   A symbol button in the header that opens a small floating panel with the
   picker and the rate warning. Present on every page; assets/js/currency.js
   updates the symbol to the visitor's chosen currency and drives the panel. */

.currency { position: relative; display: flex; }

.currency__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  min-height: 40px;
  padding: 0 var(--space-2xs);
  border: var(--border) solid var(--hairline);
  border-radius: var(--radius);
  background: var(--paper-pure);
  color: var(--graphite);
  font: inherit;
  cursor: pointer;
}
.currency__toggle:hover { border-color: var(--graphite); }
.currency__toggle:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.currency__symbol {
  font-family: var(--font-mono);
  font-size: var(--step-0);
  font-weight: 600;
  line-height: 1;
}

.currency__pop {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 60;
  width: min(20rem, calc(100vw - 2rem));
  padding: var(--space-m);
  border: var(--border) solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--paper-pure);
  box-shadow: var(--shadow-lift);
  /* Floats out from the button's top-right corner on open. */
  transform-origin: top right;
  transform: scale(0.96) translateY(-4px);
  opacity: 0;
  transition: opacity 0.16s ease, transform 0.16s ease;
}
.currency.is-open .currency__pop { transform: scale(1) translateY(0); opacity: 1; }

.currency__pop-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-s); margin-bottom: var(--space-2xs);
}
.currency__pop-title {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--grey);
}
.currency__close {
  display: inline-flex; padding: 0.25rem; margin: -0.25rem;
  border: 0; background: none; color: var(--grey); cursor: pointer;
}
.currency__close:hover { color: var(--graphite); }
.currency__close:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

.currency__options { display: grid; gap: var(--space-3xs); margin: var(--space-s) 0; }
.currency__opt {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  width: 100%;
  min-height: 44px;
  padding: 0 var(--space-s);
  border: var(--border) solid var(--hairline);
  border-radius: var(--radius);
  background: var(--paper-pure);
  color: var(--graphite);
  font: inherit;
  text-align: start;
  cursor: pointer;
}
.currency__opt:hover { border-color: var(--graphite); }
.currency__opt:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.currency__opt[aria-pressed="true"] { border-color: var(--graphite); background: var(--paper-shade); }
.currency__opt-sym { font-family: var(--font-mono); font-weight: 600; min-width: 2.5ch; }
.currency__opt-name { color: var(--grey); }
.currency__opt[aria-pressed="true"] .currency__opt-name { color: var(--graphite); }

.currency__note {
  font-size: var(--step--1);
  line-height: var(--lh-body);
  color: var(--grey);
}
.currency__note--prose { color: var(--stone-dark); margin-top: var(--space-2xs); }

/* A converted figure keeps the USD original in its title attribute. Marking
   it visually would be noise; the note already says figures are approximate
   and billed in USD. */
.money { white-space: nowrap; }

/* ---- Learning Centre (Phase 5) ------------------------------------------ */

.article-card__media { aspect-ratio: 16 / 9; }
.article-card__duration {
  position: absolute;
  inset-inline-end: var(--space-2xs);
  bottom: var(--space-2xs);
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.3em 0.6em;
  border-radius: var(--radius);
  background: rgba(28, 28, 28, 0.82);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}
.article-card__meta {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--stone-dark);
}

.article__meta {
  margin-top: var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--grey);
}
.article__intro { margin-top: var(--space-l); }
.article__intro p { max-width: var(--measure); }

/* ---- Transcript ---------------------------------------------------------- */

.transcript-nav {
  display: grid;
  gap: 0;
  margin-top: var(--space-l);
  border-top: var(--border) solid var(--hairline);
}
.transcript-nav__item {
  display: flex;
  align-items: baseline;
  gap: var(--space-s);
  min-height: 48px;
  padding: var(--space-2xs) 0;
  border-bottom: var(--border) solid var(--hairline);
  color: inherit;
  text-decoration: none;
}
.transcript-nav__item:hover { color: var(--blue-text); }
.transcript-nav__time {
  flex: 0 0 4.5rem;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--grey);
}

.transcript { margin-top: var(--space-xl); }
.transcript__section { scroll-margin-top: var(--space-2xl); }
.transcript__section + .transcript__section { margin-top: var(--space-xl); }
.transcript__heading {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-s);
  font-size: var(--step-1);
}
.transcript__time {
  flex: 0 0 auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: var(--weight-regular);
  color: var(--blue-text);
  text-decoration: none;
}
.transcript__time:hover { text-decoration: underline; }

/* ---- HTML sitemap (Phase 6) --------------------------------------------- */

.sitemap__group + .sitemap__group {
  margin-top: var(--space-xl);
  padding-top: var(--space-l);
  border-top: 1px solid var(--hairline);
}
.sitemap__heading {
  font-size: var(--step-1);
  letter-spacing: var(--tracking-heading);
}
.sitemap__list {
  margin-top: var(--space-s);
  padding: 0;
  list-style: none;
  columns: 2;
  column-gap: var(--space-l);
}
.sitemap__item {
  break-inside: avoid;
  padding: var(--space-3xs) 0;
}
.sitemap__item a {
  /* 44px is the touch target floor used everywhere else on the site. */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--graphite);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.sitemap__item a:hover,
.sitemap__item a:focus-visible {
  color: var(--blue-text);
  border-bottom-color: currentColor;
}

@media (max-width: 40rem) {
  .sitemap__list { columns: 1; }
}
