/* ============================================================
   ASKERA — shared foundation
   Tokens for colour and font live in the theme files.
   ============================================================ */

/* ---------- Fonts ----------
   One variable woff2 per family, subset to the 125 glyphs this site can
   render (Latin + every Lithuanian diacritic + the punctuation in use).
   539 KB across 18 static files became 76 KB across 3. Re-subset with
   tools/fonts.sh if the copy ever needs a character outside that set. */

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/Archivo.03afada60b.woff2") format("woff2");
}
@font-face {
  font-family: "Martian Mono";
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url("/fonts/MartianMono.709d0e1319.woff2") format("woff2");
}

/* ---------- Shared tokens ---------- */

:root {
  --sp-3xs: 0.25rem;
  --sp-2xs: 0.5rem;
  --sp-xs: 0.75rem;
  --sp-sm: 1rem;
  --sp-md: clamp(1.25rem, 2vw, 1.75rem);
  --sp-lg: clamp(2rem, 4vw, 3rem);
  --sp-xl: clamp(3rem, 6vw, 5rem);
  --sp-2xl: clamp(4.5rem, 10vw, 9rem);
  --sp-3xl: clamp(6rem, 14vw, 11.5rem);

  --fs-xs: 0.8125rem;
  --fs-sm: 0.9375rem;
  --fs-base: 1.0625rem;
  --fs-md: clamp(1.15rem, 0.9rem + 0.7vw, 1.35rem);
  --fs-lg: clamp(1.45rem, 1.1rem + 1.4vw, 1.95rem);
  --fs-xl: clamp(1.9rem, 1.3rem + 2.6vw, 2.9rem);
  --fs-2xl: clamp(2.35rem, 1.5rem + 3.9vw, 4rem);
  --fs-3xl: clamp(2.7rem, 1.6rem + 5.3vw, 5.25rem);

  --measure: 68ch;
  --wrap: 78rem;
  --gutter: clamp(1.15rem, 4vw, 2.75rem);

  --z-sticky: 100;
  --z-backdrop: 200;
  --z-dialog: 300;
  --z-tooltip: 400;

  --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
  /* Heavier, with mass behind it. Used for anything that moves a whole
     element rather than just recolouring it. */
  --ease-spring: cubic-bezier(0.32, 0.72, 0, 1);
  --dur-reveal: 820ms;
  --dur-fast: 140ms;
  --dur: 220ms;
  --dur-slow: 420ms;

  --radius: 0px;
  --radius-lg: 0px;
}

/* ============================================================
   Colour and type tokens
   The cabinetmaker's shop drawing. White paper, workshop green,
   pencil yellow, and figures that are all true.
   ============================================================ */

:root {
  --bg:          oklch(1 0 0);
  --surface:     oklch(0.975 0.004 150);
  --ink:         oklch(0.20 0.012 150);
  --ink-soft:    oklch(0.45 0.015 150);
  --brand:       oklch(0.33 0.085 150);
  --brand-deep:  oklch(0.25 0.07 150);
  --accent:      oklch(0.80 0.16 90);
  --line:        oklch(0.90 0.006 150);
  --line-strong: oklch(0.78 0.01 150);
  --on-brand:    oklch(1 0 0);
  --focus:       oklch(0.33 0.085 150);

  --font-display: "Archivo", system-ui, sans-serif;
  --font-body:    "Archivo", system-ui, sans-serif;
  --font-num:     "Martian Mono", ui-monospace, monospace;

  --header-bg:       oklch(1 0 0 / 0.88);
  --header-ink:      oklch(0.20 0.012 150);
  --header-line:     oklch(0.90 0.006 150);
  --header-btn-line: oklch(0.78 0.01 150);
  --brand-on-header: oklch(0.33 0.085 150);

  --band-bg:       oklch(0.33 0.085 150);
  --on-band:       oklch(1 0 0);
  --on-band-soft:  oklch(0.87 0.02 150);
  --on-band-line:  oklch(0.45 0.06 150);
  --band-accent:   oklch(0.83 0.15 92);

  --footer-bg:     oklch(0.975 0.004 150);
  --footer-ink:    oklch(0.45 0.015 150);
  --footer-strong: oklch(0.20 0.012 150);
  --footer-soft:   oklch(0.50 0.012 150);
  --footer-line:   oklch(0.88 0.008 150);

  --tag-bg:  oklch(0.33 0.085 150);
  --tag-ink: oklch(1 0 0);

  --callbar-bg:   oklch(1 0 0);
  --callbar-ink:  oklch(0.20 0.012 150);
  --callbar-line: oklch(0.86 0.008 150);

  --radius: 0px;

  /* Machined-panel bezel. Near-square, because the whole theme is a
     shop drawing and a rounded plate would contradict it. */
  --bezel-shell:      oklch(0.962 0.006 150);
  --bezel-line:       oklch(0.905 0.008 150);
  --bezel-line-hover: oklch(0.60 0.05 150);
  --bezel-inset:      oklch(1 0 0);
  --bezel-radius:     5px;
  --bezel-pad:        5px;

  --shadow-ambient: 0 1px 2px oklch(0.33 0.085 150 / 0.05),
                    0 10px 26px -14px oklch(0.33 0.085 150 / 0.22);
  --shadow-lift:    0 2px 4px oklch(0.33 0.085 150 / 0.06),
                    0 22px 48px -20px oklch(0.33 0.085 150 / 0.34);

  --btn-icon-bg:        oklch(0.20 0.012 150 / 0.07);
  --btn-icon-bg-hover:  oklch(0.20 0.012 150 / 0.12);
  --btn-icon-on-brand:  oklch(1 0 0 / 0.16);

  --band-bezel-shell: oklch(0.38 0.075 150);
  --band-bezel-line:  oklch(0.46 0.065 150);
  --band-bezel-core:  oklch(0.30 0.08 150);
  --band-bezel-inset: oklch(1 0 0 / 0.10);
}

/* The number font is wide. Tighten it so figures sit with the text. */
.num {
  font-size: 0.9em;
  letter-spacing: -0.06em;
}

h1,
h2 { letter-spacing: -0.035em; }

/* Signature: a dimension tick under every section heading. */
.section-head h2,
.page-head h1 {
  position: relative;
  padding-top: var(--sp-md);
}
.section-head h2::before,
.page-head h1::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 3.5rem;
  height: 8px;
  border-left: 1.5px solid var(--brand);
  border-right: 1.5px solid var(--brand);
  background:
    linear-gradient(var(--brand), var(--brand)) 0 50% / 100% 1.5px no-repeat;
}
.section-head--invert h2::before {
  border-color: var(--band-accent);
  background-image: linear-gradient(var(--band-accent), var(--band-accent));
}

/* Hero figure gets a measured frame. */
.hero__figure {
  position: relative;
  padding: 0.75rem;
  border: 1px solid var(--line);
}
.hero__figure::after {
  content: "";
  position: absolute;
  inset: 0.75rem;
  outline: 1px solid var(--line);
  outline-offset: -1px;
  pointer-events: none;
}

/* The hero sits in a half-width column, so the display scale is capped
   lower than the page scale. Above this it wraps to four lines. */
.hero__title {
  letter-spacing: -0.04em;
  font-size: clamp(2.4rem, 1.5rem + 3.1vw, 4rem);
}

/* Rooms read as a spec table. */
.room__link { border-width: 1px; }
.room__count { letter-spacing: -0.05em; }

/* Steps: numbers are real measurements of the process. */
.step { border-top-width: 2px; }
.step__num::before { content: "0"; }

.filter[aria-pressed="true"] .filter__count { opacity: 0.9; }

/* ---------- Reset ---------- */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 6rem;
}

body {
  min-height: 100svh;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }

a { color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

p { text-wrap: pretty; }

ul, ol { list-style: none; padding: 0; }

::selection { background: var(--brand); color: var(--bg); }

/* ---------- Focus ---------- */

:where(a, button, [tabindex]):focus-visible {
  outline: 3px solid var(--focus, var(--brand));
  outline-offset: 3px;
}

.skip {
  position: absolute;
  left: var(--sp-sm);
  top: var(--sp-sm);
  z-index: var(--z-tooltip);
  padding: var(--sp-xs) var(--sp-sm);
  background: var(--brand);
  color: var(--on-brand);
  font-weight: 600;
  border-radius: 999px;
  /* translate, not top: never animate a layout property */
  transform: translateY(-300%);
  transition: transform var(--dur) var(--ease-spring);
}
.skip:focus { transform: translateY(0); }

/* ---------- Utilities ---------- */

.wrap {
  width: min(100% - (var(--gutter) * 2), var(--wrap));
  margin-inline: auto;
}

.num {
  font-family: var(--font-num);
  font-feature-settings: "tnum" 1;
  letter-spacing: -0.01em;
}

/* ============================================================
   Header
   ============================================================ */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--header-bg);
  color: var(--header-ink);
  border-bottom: 1px solid var(--header-line);
  backdrop-filter: saturate(1.4) blur(10px);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--sp-md);
  min-height: 4.25rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  text-decoration: none;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: 0.06em;
  margin-inline-end: auto;
}
.brand__mark { color: var(--brand-on-header); display: grid; place-items: center; }

.nav {
  display: flex;
  gap: clamp(0.7rem, 3vw, var(--sp-md));
  font-size: clamp(0.85rem, 0.6rem + 1vw, var(--fs-sm));
  font-weight: 500;
}
.nav a {
  text-decoration: none;
  padding: 0.4rem 0;
  border-bottom: 2px solid transparent;
  transition: border-color var(--dur) var(--ease-out-quint), opacity var(--dur);
}
.nav a:hover { border-color: currentColor; }
.nav a[aria-current="page"] { border-color: var(--brand-on-header); }

/* On a phone the header carries the pages and the sticky bar at the bottom
   carries both phone numbers, so the header call button would be a third
   copy of the same number. Drop it and the three links fit on one line. */
@media (max-width: 55.999rem) {
  .brand { margin-inline-end: auto; }
  /* Scoped to the header so it beats .btn on specificity. The same rule
     written as `.btn--call` loses, because .btn is defined further down. */
  .site-header .btn--call { display: none; }
}

/* At 320px four links plus the wordmark need 339px of a 283px row. The
   mark alone still reads as the logo and still links home, and the h1
   says the name again immediately below. */
@media (max-width: 22.5rem) {
  .brand__text { display: none; }
  .nav { gap: 0.62rem; font-size: 0.82rem; }
  /* The mark is 22px; padding brings the tap target to 44px without moving
     it optically, so it still lines up with the gutter. */
  .brand {
    padding: 0.7rem;
    margin-inline-start: -0.7rem;
    min-block-size: 2.75rem;
  }
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 2.9rem;
  padding: 0.65rem 1.15rem;
  border-radius: var(--radius);
  font-weight: 600;
  font-size: var(--fs-sm);
  text-decoration: none;
  border: 1.5px solid transparent;
  transition: background-color var(--dur) var(--ease-out-quint),
              color var(--dur) var(--ease-out-quint),
              border-color var(--dur) var(--ease-out-quint),
              transform var(--dur-fast) var(--ease-out-quint);
}
.btn:active { transform: translateY(1px); }

.btn--primary {
  background: var(--brand);
  color: var(--on-brand);
  font-size: var(--fs-base);
  min-height: 3.25rem;
  padding: 0.8rem 1.5rem;
}
.btn--primary:hover { background: var(--brand-deep); }

.btn--ghost {
  border-color: var(--line-strong);
  color: var(--ink);
  min-height: 3.25rem;
  padding: 0.8rem 1.5rem;
  font-size: var(--fs-base);
}
.btn--ghost:hover { border-color: var(--ink); background: var(--surface); }

.btn--call {
  border-color: var(--header-btn-line);
  color: var(--header-ink);
  padding: 0.55rem 0.9rem;
  min-height: 2.75rem;
}
.btn--call:hover { background: var(--brand); color: var(--on-brand); border-color: var(--brand); }
.btn--call .btn__label { display: none; }

@media (min-width: 26rem) {
  .btn--call .btn__label { display: inline; }
}

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 2px solid var(--brand);
  padding-bottom: 0.15rem;
  transition: gap var(--dur) var(--ease-out-quint);
}
.link-arrow:hover { gap: 0.8rem; }

/* ============================================================
   Sections
   ============================================================ */

.section-head {
  max-width: var(--measure);
  margin-bottom: var(--sp-lg);
}
.section-head h2 { font-size: var(--fs-xl); margin-bottom: var(--sp-xs); }
.section-head p { color: var(--ink-soft); font-size: var(--fs-md); }
.section-head--invert p { color: var(--on-band-soft); }

.page-head {
  padding-block: var(--sp-xl) var(--sp-lg);
}
.page-head h1 { font-size: var(--fs-2xl); margin-bottom: var(--sp-sm); }
.page-head p { color: var(--ink-soft); font-size: var(--fs-md); max-width: var(--measure); }

/* ---------- Hero: shared ---------- */

.hero__title { font-size: var(--fs-3xl); }
.hero__lead {
  font-size: var(--fs-md);
  color: var(--ink-soft);
  max-width: 46ch;
  margin-top: var(--sp-md);
}
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-sm);
  margin-top: var(--sp-lg);
}
/* Stacked buttons of different widths read as a mistake. Below the wrap
   point they share the full column; above it they size to their labels. */
@media (max-width: 33.999rem) {
  .hero__actions { display: grid; grid-template-columns: 1fr; }
  .hero__actions .btn { width: 100%; justify-content: space-between; }
}
/* Shown only when the structure folds the wardrobe argument into the hero. */
.hero__proof {
  margin-top: var(--sp-sm);
  padding-top: var(--sp-sm);
  border-top: 1px solid var(--line);
  max-width: 46ch;
  font-size: var(--fs-sm);
  color: var(--ink-soft);
}
.hero__note {
  margin-top: var(--sp-md);
  font-size: var(--fs-sm);
  color: var(--ink-soft);
}

/* ---------- Hero A: drawing ---------- */

.hero--drawing { padding-block: var(--sp-xl) var(--sp-lg); }
.hero__grid {
  display: grid;
  gap: var(--sp-lg);
  align-items: center;
}
.hero__figure img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

@media (min-width: 56rem) {
  .hero__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: var(--sp-xl); }
}

/* ---------- Dimension rules (theme A) ---------- */

.rule-row {
  display: grid;
  /* Three items. auto-fit gave two columns on a phone and left the third
     alone beside a gap, so the count is explicit at each size. */
  grid-template-columns: 1fr;
  gap: var(--sp-md);
  margin-top: var(--sp-xl);
  padding-top: var(--sp-md);
  border-top: 1px solid var(--line);
}
.rule { display: grid; gap: 0.1rem; position: relative; padding-top: 0.9rem; align-content: end; }
/* The third value uses the display face at a smaller size, which shortened
   its row and lifted its label above the other two. */
.rule__value { min-height: 1.6em; display: flex; align-items: flex-end; }
@media (min-width: 34rem) { .rule-row { grid-template-columns: repeat(3, 1fr); } }
.rule__line {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 7px;
  border-left: 1px solid var(--brand);
  border-right: 1px solid var(--brand);
}
.rule__line::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--brand);
}
.rule__value { font-size: var(--fs-lg); font-weight: 600; color: var(--brand); line-height: 1.1; }
.rule__label { font-size: var(--fs-xs); color: var(--ink-soft); text-transform: uppercase; letter-spacing: 0.08em; }

/* A word, not a figure. The mono face is for numbers only, and a long word
   set in it drowns the two real figures beside it. */
.rule--text .rule__value {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  letter-spacing: -0.01em;
}

/* ---------- Argument ---------- */

.argument { padding-block: var(--sp-2xl); }
.argument__grid { display: grid; gap: var(--sp-lg); align-items: center; }
.argument__figure img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.argument__copy h2 { font-size: var(--fs-xl); margin-bottom: var(--sp-md); }
.argument__copy p { color: var(--ink-soft); max-width: 52ch; margin-bottom: var(--sp-sm); }
.argument__copy .link-arrow { margin-top: var(--sp-sm); }

@media (min-width: 56rem) {
  .argument__grid { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr); gap: var(--sp-2xl); }
}

/* ---------- Rooms ---------- */

.rooms { padding-block: var(--sp-2xl); background: var(--surface); }

.room-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--sp-md);
}
.room__link {
  display: grid;
  gap: var(--sp-sm);
  height: 100%;
  align-content: start;
  text-decoration: none;
  background: var(--surface);
  border-radius: max(0px, calc(var(--bezel-radius) - var(--bezel-pad)));
  box-shadow: inset 0 1px 0 var(--bezel-inset);
  overflow: hidden;
}
.room__media { display: block; overflow: hidden; }
.room__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: scale var(--dur-slow) var(--ease-out-quart);
}
.room:hover .room__media img { scale: 1.045; }
.room__body { display: grid; gap: 0.3rem; padding: 0 var(--sp-sm) var(--sp-md); align-content: start; }
.room__name { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-md); line-height: 1.2; }
.room__count {
  font-size: var(--fs-xs);
  color: var(--brand);
  font-weight: 600;
}
.room__count .room__unit { font-family: var(--font-body); font-weight: 400; color: var(--ink-soft); }
.room__text { font-size: var(--fs-sm); color: var(--ink-soft); line-height: 1.5; }

/* ---------- Process ---------- */

.process {
  padding-block: var(--sp-2xl);
  background: var(--band-bg);
  color: var(--on-band);
}
.process .section-head h2 { color: var(--on-band); }

.process__grid { display: grid; gap: var(--sp-lg); }

.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--sp-lg) var(--sp-md);
  counter-reset: step;
}

.step { display: grid; gap: 0.4rem; align-content: start; padding-top: var(--sp-sm); border-top: 2px solid var(--on-band-line); }
.step__num {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--band-accent);
  letter-spacing: 0.1em;
}
.step__title { font-size: var(--fs-md); color: var(--on-band); }
.step__text { font-size: var(--fs-sm); color: var(--on-band-soft); line-height: 1.55; }

/* ---------- Preview strip ---------- */

.preview { padding-block: var(--sp-2xl); }

.preview__strip {
  display: flex;
  gap: var(--sp-2xs);
  overflow-x: auto;
  padding-inline: var(--gutter);
  padding-bottom: var(--sp-sm);
  scroll-snap-type: x mandatory;
  /* Without this, mandatory snap aligns item 1 to the padding-box edge and
     the strip loads already scrolled by its own gutter. */
  scroll-padding-inline-start: var(--gutter);
  scrollbar-width: thin;
}
.preview__item { flex: 0 0 auto; scroll-snap-align: start; }
.preview__item img {
  height: clamp(11rem, 26vw, 18rem);
  width: auto;
  max-width: none;
  object-fit: cover;
}
.preview__more { margin-top: var(--sp-lg); }

/* ---------- Contact band ---------- */

.contact-band {
  padding-block: var(--sp-2xl);
  background: var(--band-bg);
  color: var(--on-band);
}
.contact-band__grid { display: grid; gap: var(--sp-lg); }
.contact-band__copy h2 { font-size: var(--fs-xl); margin-bottom: var(--sp-md); color: var(--on-band); }
.contact-band__copy p { color: var(--on-band-soft); max-width: 46ch; }
.contact-band__where { margin-top: var(--sp-md); }
.contact-band__where a { color: var(--on-band); }

.contact-band__note {
  margin-top: var(--sp-2xs);
  font-size: var(--fs-sm);
  color: var(--on-band-soft);
}

.contact-band__list {
  display: grid;
  gap: var(--sp-sm);
  align-content: start;
  grid-template-columns: 1fr;
}
.contact-band__list > * { min-width: 0; container-type: inline-size; }
/* Two across only when the list actually has the room: full width on a
   phone, or a wide enough viewport once the band itself has split in two. */
/* Two across only when 17rem of inner width exists for the card. Viewport
   breakpoints cannot know the column width, which is how a nowrap phone
   number ended up clipped by overflow:hidden between 1120 and 1271px. */
.contact-band__list { grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr)); }
@media (min-width: 56rem) {
  .contact-band__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: var(--sp-2xl); align-items: start; }
}

.contact-card {
  display: grid;
  gap: 0.2rem;
  padding: var(--sp-md);
}
.contact-card__role { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.1em; color: var(--on-band-soft); }
.contact-card__name { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-md); }
.contact-card__phone {
  /* Sized from the card, not the window, and never nowrap: a clipped
     number is worse than one that breaks at its own space. */
  font-size: clamp(1rem, 6.6cqi, 1.5rem);
  font-weight: 600;
  color: var(--band-accent);
  text-decoration: none;
  margin-top: 0.25rem;
}
.contact-card__phone:hover { text-decoration: underline; text-underline-offset: 4px; }
.contact-card__mail { font-size: var(--fs-sm); color: var(--on-band-soft); word-break: break-word; }

/* ============================================================
   Gallery
   ============================================================ */

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2xs);
  padding-bottom: var(--sp-md);
  border-bottom: 1px solid var(--line);
}
.filter {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 2.75rem;
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  font-size: var(--fs-sm);
  font-weight: 500;
  transition: background-color var(--dur) var(--ease-out-quint),
              border-color var(--dur) var(--ease-out-quint),
              color var(--dur) var(--ease-out-quint);
}
.filter:hover { border-color: var(--ink); }
.filter[aria-pressed="true"] { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.filter__count { font-size: var(--fs-xs); opacity: 0.75; }

.filter-status {
  margin-block: var(--sp-md);
  font-size: var(--fs-sm);
  color: var(--ink-soft);
}

.photo-grid {
  columns: 1;
  column-gap: var(--sp-2xs);
  margin-bottom: var(--sp-2xl);
  transition: opacity var(--dur) var(--ease-out-quint);
}
.photo-grid.is-swapping { opacity: 0; }

@media (min-width: 26rem) { .photo-grid { columns: 2; } }
@media (min-width: 52rem) { .photo-grid { columns: 3; } }
@media (min-width: 78rem) { .photo-grid { columns: 4; } }

.photo {
  break-inside: avoid;
  margin-bottom: var(--sp-2xs);
}
.photo[hidden] { display: none; }

.photo__btn {
  position: relative;
  display: block;
  width: 100%;
  overflow: hidden;
  background: var(--surface);
}
.photo__btn img {
  width: 100%;
  transition: scale var(--dur-slow) var(--ease-out-quart),
              opacity var(--dur) var(--ease-out-quint);
}
.photo__btn:hover img { scale: 1.03; }

.photo__tag {
  position: absolute;
  left: 0;
  bottom: 0;
  padding: 0.35rem 0.6rem;
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  background: var(--tag-bg);
  color: var(--tag-ink);
  opacity: 0;
  translate: 0 0.35rem;
  transition: opacity var(--dur) var(--ease-out-quint), translate var(--dur) var(--ease-out-quint);
}
.photo__btn:hover .photo__tag,
.photo__btn:focus-visible .photo__tag { opacity: 1; translate: 0 0; }

/* ---------- Lightbox ---------- */

.lightbox {
  width: 100vw;
  max-width: 100vw;
  height: 100svh;
  max-height: 100svh;
  padding: 0;
  border: 0;
  background: oklch(0.07 0 0 / 0.97);
  color: oklch(0.97 0 0);
  z-index: var(--z-dialog);
}
.lightbox::backdrop { background: oklch(0.07 0 0 / 0.9); }
.lightbox[open] { display: grid; place-items: center; }

.lightbox__figure {
  display: grid;
  gap: var(--sp-sm);
  place-items: center;
  padding: var(--sp-2xs);
  max-width: min(100vw, 82rem);
}
.lightbox__figure img {
  max-height: 88svh;
  max-width: 100%;
  width: auto;
  object-fit: contain;
  animation: lb-in var(--dur) var(--ease-out-quint);
}
.lightbox__caption {
  display: flex;
  gap: var(--sp-sm);
  align-items: baseline;
  font-size: var(--fs-sm);
  color: oklch(0.78 0 0);
}

@keyframes lb-in { from { opacity: 0; scale: 0.98; } to { opacity: 1; scale: 1; } }

.lightbox__close,
.lightbox__nav {
  position: fixed;
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  color: oklch(0.97 0 0);
  /* A white glyph on a white scrim over a white kitchen is invisible at any
     alpha. The control carries its own dark ground instead. */
  background: oklch(0.15 0 0 / 0.62);
  box-shadow: 0 1px 6px oklch(0 0 0 / 0.45);
  border-radius: 999px;
  transition: background-color var(--dur) var(--ease-out-quint);
  z-index: 1;
}
.lightbox__close:hover,
.lightbox__nav:hover { background: oklch(0.24 0 0 / 0.82); }
.lightbox__close { top: var(--sp-sm); right: var(--sp-sm); }
.lightbox__nav--prev { left: var(--sp-2xs); top: 50%; translate: 0 -50%; }
.lightbox__nav--next { right: var(--sp-2xs); top: 50%; translate: 0 -50%; }

@media (min-width: 40rem) {
  .lightbox__nav--prev { left: var(--sp-md); }
  .lightbox__nav--next { right: var(--sp-md); }
}

/* ============================================================
   About + contacts
   ============================================================ */

.prose-block { padding-block: var(--sp-lg) var(--sp-2xl); }
.prose-block__grid { display: grid; gap: var(--sp-xl); align-items: start; }
@media (min-width: 60rem) {
  .prose-block__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 0.62fr); gap: var(--sp-2xl); }
}

.prose { max-width: var(--measure); }
.prose h2 { font-size: var(--fs-lg); margin-top: var(--sp-xl); margin-bottom: var(--sp-sm); }
.prose p { margin-bottom: var(--sp-sm); color: var(--ink-soft); }
.prose__lead { font-size: var(--fs-md); color: var(--ink) !important; }
.prose__note { font-size: var(--fs-sm); padding-left: var(--sp-sm); border-left: 1px solid var(--line-strong); }
.prose__list { display: grid; gap: var(--sp-2xs); margin-top: var(--sp-sm); }
.prose__list li { position: relative; padding-left: 1.6rem; color: var(--ink-soft); }
.prose__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 0.85rem;
  height: 2px;
  background: var(--brand);
}

.fact-card { padding: var(--sp-md); }
.fact-card__title { font-size: var(--fs-md); margin-bottom: var(--sp-sm); }
.fact-card__figure { margin-top: var(--sp-md); }
.fact-card__figure img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.fact-card__figure figcaption { margin-top: var(--sp-2xs); font-size: var(--fs-xs); color: var(--ink-soft); }

.fact-list { display: grid; grid-template-columns: auto 1fr; gap: 0.35rem var(--sp-sm); font-size: var(--fs-sm); }
.fact-list dt { color: var(--ink-soft); }
.fact-list dd { font-weight: 500; }

.contacts { padding-block: var(--sp-lg) var(--sp-2xl); }
.contacts__grid { display: grid; gap: var(--sp-md); margin-bottom: var(--sp-2xl); }
.contacts__grid > * { min-width: 0; container-type: inline-size; }
/* Same rule as the contact band: content decides, not the viewport. */
.contacts__grid { grid-template-columns: repeat(auto-fit, minmax(min(21rem, 100%), 1fr)); }

.contact-full {
  display: grid;
  gap: 0.25rem;
  padding: var(--sp-lg) var(--sp-md);
}
.contact-full__role { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-soft); }
.contact-full__name { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-lg); line-height: 1.15; }
.contact-full__phone {
  font-size: clamp(1.25rem, 7.4cqi, 2.4rem);
  font-weight: 700;
  color: var(--brand);
  text-decoration: none;
  margin-top: var(--sp-2xs);
  line-height: 1.1;
}
.contact-full__phone:hover { text-decoration: underline; text-underline-offset: 5px; }
.contact-full__mail { font-size: var(--fs-sm); color: var(--ink-soft); word-break: break-word; }

.contacts__where { display: grid; gap: var(--sp-lg); }
@media (min-width: 50rem) { .contacts__where { grid-template-columns: repeat(3, 1fr); } }
.contacts__where h2 { font-size: var(--fs-md); margin-bottom: var(--sp-2xs); }
.contacts__where p { color: var(--ink-soft); font-size: var(--fs-sm); margin-bottom: var(--sp-2xs); }
.contacts__address { font-size: var(--fs-base) !important; color: var(--ink) !important; }

/* ============================================================
   Footer
   ============================================================ */

.site-footer {
  padding-block: var(--sp-xl) var(--sp-lg);
  background: var(--footer-bg);
  color: var(--footer-ink);
  border-top: 1px solid var(--footer-line);
  font-size: var(--fs-sm);
}
.site-footer__grid { display: grid; gap: var(--sp-lg); }
@media (min-width: 46rem) { .site-footer__grid { grid-template-columns: repeat(3, 1fr); } }
.site-footer__block p { margin-bottom: var(--sp-2xs); }
.site-footer__name { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-md); color: var(--footer-strong); }
.site-footer__person { font-weight: 600; color: var(--footer-strong); }
.site-footer a { text-decoration: none; border-bottom: 1px solid var(--footer-line); }
.site-footer a:hover { border-color: currentColor; }
.site-footer__legal { color: var(--footer-soft); }
.site-footer__copy { margin-top: var(--sp-sm); }

/* ============================================================
   Sticky call bar (mobile everywhere, desktop on Studija)
   ============================================================ */

.callbar {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: var(--z-sticky);
  display: flex;
  gap: 1px;
  background: var(--callbar-line);
  border-top: 1px solid var(--callbar-line);
}
.callbar a {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-height: 3.25rem;
  padding-inline: 0.3rem;
  background: var(--callbar-bg);
  color: var(--callbar-ink);
  font-weight: 600;
  font-size: clamp(0.78rem, 0.55rem + 1vw, 0.95rem);
  text-decoration: none;
  white-space: nowrap;
}
/* The mono figure font is too wide for a half-width bar on a 360px phone. */
.callbar .num { font-family: var(--font-body); letter-spacing: 0; font-size: 1em; }
.callbar svg { flex: none; }
/* flex:1 forces halves the longer label cannot fit: at 320px the second
   link overflowed by 6px and its icon landed on the first number. Below
   360px the first name goes and the number stands alone. */
@media (max-width: 22.5rem) {
  .callbar__who { display: none; }
  .callbar a { gap: 0.3rem; font-size: 0.8rem; }
}
.callbar a:hover { background: var(--brand); color: var(--on-brand); }

@media (min-width: 56rem) {
  .callbar { display: none; }
  body { padding-bottom: 0; }
}
@media (max-width: 55.999rem) {
  body { padding-bottom: 3.35rem; }
}

/* ============================================================
   Motion
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
  .room__link:hover { transform: none; }
  .photo__btn:hover img,
  .room__link:hover .room__media img { scale: 1; }
}

/* ============================================================
   Hero drawing (Tikslumas)
   A cabinetmaker's elevation instead of a photograph. Everything
   is stroked, so it stays crisp at any size and weighs ~3 kB.
   ============================================================ */

.drawing { width: 100%; height: auto; overflow: visible; }

.drawing__cabinet rect,
.drawing__cabinet line,
.drawing__cabinet path {
  fill: none;
  stroke: var(--ink);
  stroke-width: 2;
  stroke-linecap: square;
}
.drawing__top { fill: var(--brand); stroke: var(--brand); }
.drawing__hood { stroke-width: 1.6; }
.drawing__hob { stroke: var(--bg); stroke-width: 3; }
.drawing__oven { stroke-width: 1.6; }
.drawing__handle line { stroke-width: 3; stroke: var(--brand); stroke-linecap: round; }
.drawing__floor { stroke-width: 3; }

.drawing__dims line { stroke: var(--brand); stroke-width: 1; }
.drawing__dims .drawing__tick { stroke-width: 1.5; }
.drawing__fig {
  fill: var(--brand);
  font-family: var(--font-num);
  font-size: 21px;
  letter-spacing: -0.08em;
}
.drawing__note {
  fill: var(--ink-soft);
  font-family: var(--font-body);
  font-size: 17px;
  letter-spacing: 0.04em;
}

/* The dimension lines draw themselves in, the way a drawing is made.
   Opt in only when motion is welcome, so the default state is complete. */
@media (prefers-reduced-motion: no-preference) {
  .drawing__dims line {
    /* Longer than the longest dimension line, or the dash pattern shows
       as a gap once the animation finishes. */
    stroke-dasharray: 900;
    stroke-dashoffset: 900;
    animation: draw-in 900ms var(--ease-out-quint) forwards;
  }
  .drawing__dims .drawing__tick { animation-duration: 420ms; }
  .drawing__fig, .drawing__note {
    opacity: 0;
    animation: fade-in 500ms var(--ease-out-quint) 620ms forwards;
  }
}
@keyframes draw-in { to { stroke-dashoffset: 0; } }
@keyframes fade-in { to { opacity: 1; } }

/* ============================================================
   Double bezel
   A card is never laid flat on the page. It is a plate seated in
   a tray: outer shell with a hairline, inner core with its own
   ground and a top highlight, radii kept concentric.
   ============================================================ */

.bezel {
  padding: var(--bezel-pad);
  background: var(--bezel-shell);
  border: 1px solid var(--bezel-line);
  border-radius: var(--bezel-radius);
  box-shadow: var(--shadow-ambient);
  transition: border-color var(--dur) var(--ease-spring),
              box-shadow var(--dur-slow) var(--ease-spring),
              transform var(--dur-slow) var(--ease-spring);
}
.bezel__core {
  height: 100%;
  background: var(--surface);
  border-radius: max(0px, calc(var(--bezel-radius) - var(--bezel-pad)));
  box-shadow: inset 0 1px 0 var(--bezel-inset);
  overflow: hidden;
}

/* ---------- Rooms as seated plates ---------- */

.room { /* the tray */
  padding: var(--bezel-pad);
  background: var(--bezel-shell);
  border: 1px solid var(--bezel-line);
  border-radius: var(--bezel-radius);
  box-shadow: var(--shadow-ambient);
  transition: border-color var(--dur) var(--ease-spring),
              box-shadow var(--dur-slow) var(--ease-spring),
              transform var(--dur-slow) var(--ease-spring);
}
.room:hover {
  border-color: var(--bezel-line-hover);
  box-shadow: var(--shadow-lift);
  transform: translate3d(0, -3px, 0);
}

/* ---------- CTA: the nested icon island ---------- */

.btn__text { display: inline-flex; align-items: baseline; gap: 0.4rem; }
.btn__icon {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  flex: none;
  margin-left: 0.35rem;
  margin-right: -0.5rem;
  border-radius: 999px;
  background: var(--btn-icon-bg);
  transition: transform var(--dur) var(--ease-spring),
              background-color var(--dur) var(--ease-spring);
}
.btn--primary .btn__icon { background: var(--btn-icon-on-brand); }
.btn:hover .btn__icon { transform: translate3d(2px, -1px, 0) scale(1.06); }
.btn--ghost:hover .btn__icon { background: var(--btn-icon-bg-hover); }

.btn--primary, .btn--ghost { border-radius: 999px; padding-inline: 1.35rem; }
.btn:active { transform: scale(0.985); }

/* ============================================================
   Scroll entry
   The default state is fully visible. JavaScript only hides an
   element at the moment it commits to observing it, and a
   failsafe clears everything if the observer never fires.
   ============================================================ */

[data-reveal].is-armed {
  opacity: 0;
  transform: translate3d(0, 2rem, 0);
  filter: blur(7px);
}
[data-reveal].is-shown {
  opacity: 1;
  transform: none;
  filter: none;
  transition: opacity var(--dur-reveal) var(--ease-spring),
              transform var(--dur-reveal) var(--ease-spring),
              filter var(--dur-reveal) var(--ease-spring);
}

/* A group staggers its children instead of fading as one block.
   The entry is an animation, not a transition, for two reasons: a
   `transition` here would replace the one the card already declares for
   its hover lift, and the stagger delay would ride along with it, so the
   eighth card would wait 315ms to answer a mouse. An animation composes
   with the card's own transition instead of overwriting it. */
[data-reveal="group"].is-armed {
  opacity: 1;
  transform: none;
  filter: none;
}
[data-reveal="group"].is-armed > * {
  opacity: 0;
  translate: 0 1.5rem;
}
[data-reveal="group"].is-shown > * {
  animation: reveal-up var(--dur-reveal) var(--ease-spring) var(--stagger, 0ms) both;
}
@keyframes reveal-up {
  from { opacity: 0; translate: 0 1.5rem; }
  to   { opacity: 1; translate: none; }
}
[data-reveal="group"].is-shown > :nth-child(2) { --stagger: 55ms; }
[data-reveal="group"].is-shown > :nth-child(3) { --stagger: 110ms; }
[data-reveal="group"].is-shown > :nth-child(4) { --stagger: 165ms; }
[data-reveal="group"].is-shown > :nth-child(5) { --stagger: 210ms; }
[data-reveal="group"].is-shown > :nth-child(6) { --stagger: 250ms; }
[data-reveal="group"].is-shown > :nth-child(7) { --stagger: 285ms; }
[data-reveal="group"].is-shown > :nth-child(n+8) { --stagger: 315ms; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal].is-armed { opacity: 1; transform: none; filter: none; }
  [data-reveal="group"].is-armed > * { opacity: 1; translate: none; }
  [data-reveal="group"].is-shown > * { animation: none; }
  .room:hover { transform: none; }
  .btn:active { transform: none; }
  .btn:hover .btn__icon { transform: none; }
}

/* The bezel sitting on a dark band needs its own shell, or the tray
   disappears into the band behind it. */
.bezel--band {
  background: var(--band-bezel-shell);
  border-color: var(--band-bezel-line);
  box-shadow: none;
}
.bezel--band .bezel__core {
  background: var(--band-bezel-core);
  box-shadow: inset 0 1px 0 var(--band-bezel-inset);
}

.contact-band__list .bezel { display: block; }
.contacts__grid .bezel { display: block; }

/* The figures band. It used to live inside the hero, which made the hero
   carry five blocks; a trust strip belongs directly below, not inside. */
.figures {
  padding-block: var(--sp-lg);
  border-bottom: 1px solid var(--line);
}
.figures .rule-row { margin-top: 0; padding-top: 0; border-top: 0; }

/* Filter chips are interactive, so they take the interactive shape.
   Square chips beside pill buttons is two shape systems on one page. */
.filter { border-radius: 999px; }

/* Icons come from one family at one weight. */
.icon { flex: none; display: block; }
.theme-switch__chev { display: grid; place-items: center; flex: none; color: oklch(0.66 0 0); transition: rotate 200ms ease; }
.theme-switch__toggle[aria-expanded="true"] .theme-switch__chev { rotate: 180deg; }

/* ============================================================
   Error pages
   Caddy serves these for any path, so they carry the header,
   the footer and the phone number. A lost visitor is still a
   visitor who wanted a carpenter.
   ============================================================ */

.errorpage { padding-block: var(--sp-2xl) var(--sp-3xl); }
.errorpage__code {
  font-size: var(--fs-md);
  font-weight: 600;
  color: var(--brand);
  letter-spacing: 0.02em;
  margin-bottom: var(--sp-sm);
}
.errorpage h1 { font-size: var(--fs-2xl); margin-bottom: var(--sp-md); }
.errorpage__lead {
  font-size: var(--fs-md);
  color: var(--ink-soft);
  max-width: 52ch;
}
.errorpage .hero__actions { margin-top: var(--sp-lg); }
.errorpage__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-md);
  margin-top: var(--sp-xl);
  padding-top: var(--sp-md);
  border-top: 1px solid var(--line);
  font-size: var(--fs-sm);
}
.errorpage__links a { color: var(--ink-soft); text-underline-offset: 4px; }
.errorpage__links a:hover { color: var(--brand); }

/* ============================================================
   Services sold on their own
   Cutting and edge banding are bought by people who are not
   buying furniture, so this block is specification, not sales:
   no photograph, no card, just the figures that answer the
   question they arrived with.
   ============================================================ */

.services { padding-block: var(--sp-2xl); }

.services__grid {
  display: grid;
  gap: var(--sp-lg);
  padding-top: var(--sp-md);
  border-top: 1px solid var(--line);
}
@media (min-width: 46rem) {
  .services__grid { grid-template-columns: 1fr 1fr; gap: var(--sp-xl); }
}

.service__name {
  font-size: var(--fs-lg);
  margin-bottom: var(--sp-2xs);
}
.service__text {
  color: var(--ink-soft);
  max-width: 46ch;
  margin-bottom: var(--sp-md);
}

.service__spec {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2xs);
}
.service__spec li {
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--bezel-radius);
  font-size: var(--fs-sm);
  color: var(--ink);
  white-space: nowrap;
}
.service__spec .num { color: var(--brand); font-weight: 600; }

.services__cta { display: flex; flex-wrap: wrap; gap: var(--sp-sm); margin-top: var(--sp-lg); }
@media (max-width: 33.999rem) {
  .services__cta { display: grid; grid-template-columns: 1fr; }
  .services__cta .btn { width: 100%; justify-content: space-between; }
}

/* ============================================================
   Services page
   Grouped rather than numbered: the page below it already uses
   01 to 04 for the process, and two numbered sequences on one
   page read as one broken list.
   ============================================================ */

.servicelist { padding-block: var(--sp-lg) var(--sp-2xl); }

.servicegroup { padding-block: var(--sp-xl); border-top: 1px solid var(--line); }
.servicegroup:last-child { border-bottom: 1px solid var(--line); }

.servicegroup__head { margin-bottom: var(--sp-lg); }
.servicegroup__name { font-size: var(--fs-xl); margin-bottom: var(--sp-3xs); }
.servicegroup__note { color: var(--ink-soft); }

.servicegroup__items { display: grid; gap: var(--sp-lg); }
@media (min-width: 52rem) {
  .servicegroup { display: grid; grid-template-columns: 14rem minmax(0, 1fr); gap: var(--sp-xl); }
  .servicegroup__head { margin-bottom: 0; }
  .servicegroup__name { font-size: var(--fs-lg); }
  .servicegroup__items { grid-template-columns: 1fr 1fr; gap: var(--sp-xl); }
}

.servicerow__name { font-size: var(--fs-md); margin-bottom: var(--sp-2xs); }
.servicerow__text { color: var(--ink-soft); max-width: 46ch; margin-bottom: var(--sp-md); }
.servicerow__spectitle {
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-soft);
  margin-bottom: var(--sp-2xs);
}

/* The footer says what the company is, not just what it is called. */
.site-footer__about {
  max-width: 46ch;
  line-height: 1.6;
  margin-bottom: var(--sp-sm);
}

/* The filter chips do nothing without JavaScript, so they are not shown
   without it. The grid still renders all 112 photos and every tile is a
   real link to the full image, which is what PRODUCT.md promises. */
.no-js .filter-bar,
.no-js .filter-status { display: none; }
