/* Signature Art & Lighting Inc. — gateway page
   Structure from Wireframes/01-gateway-entry.png: title, search, two panels,
   quote band, footer. Nothing else on this page.

   Colour, type and spacing are the design skill's own, not ours:
   palette "Teal on paper", the "Big Shoulders / Public Sans" type system
   (a tall gothic drawn from city signage, over a plain public-service sans),
   and the layout reference's tight margins and 120–240px section gaps. */

:root {
  /* Palette — dealt by the skill ("Teal on paper"): cool white paper and one
     teal for every word, shape and button, no black anywhere. */
  --bg: #f7f9f8;
  --surface: #ebf0ee;
  --ink: #06525c;
  --muted: #2f737d;
  --accent: #06525c;
  --accent-ink: #f7f9f8;
  /* Paper-coloured type for the places that sit on a dark photograph or on
     the inverted teal field: the panels and the footer. */
  --on-dark: #f7f9f8;

  /* Type steps — from the Big Shoulders sheet. Condensed capitals carry far
     more letters per line than a serif, so the display step runs large. */
  --step-small: clamp(0.8125rem, 0.79rem + 0.1vw, 0.875rem);
  --step-body: clamp(1.0625rem, 1rem + 0.25vw, 1.1875rem);
  --step-lead: clamp(1.25rem, 1.1rem + 0.7vw, 1.625rem);
  --step-head: clamp(2.5rem, 1.2rem + 5vw, 5.5rem);
  /* Section titles inside a page ("What’s included", "Our work"...): smaller
     than the page title (owner, 2026-10-25: the step-head size was too big). */
  --step-section: clamp(1.75rem, 1.3rem + 1.6vw, 3rem);

  --font-display: "Big Shoulders", "Arial Narrow", "Helvetica Neue", Arial, sans-serif;
  --font-text: "Public Sans", "Helvetica Neue", Arial, sans-serif;

  /* Spacing — the skill's layout reference: tight margins so content reaches
     the edges, the page capped only on very wide screens, and sections set
     120–240px apart on desktop, 72–112px on a phone. */
  --gutter: clamp(1rem, 2.2vw, 2rem);
  --shell: 120rem;
  --section-gap: clamp(4.5rem, 9vw, 14rem);
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-text);
  font-kerning: normal;
  font-size: var(--step-body);
  line-height: 1.5;
}

img { display: block; max-width: 100%; height: auto; }
/* Browsers give buttons their own system font; ours use the page's. */
button { font-family: inherit; }
a { color: inherit; }
p { margin: 0; }

/* Display settings from the sheet: weight 800, capitals, almost no tracking
   and leading tighter than the cap height's own spacing. */
h1, h2 {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.005em;
  line-height: 0.88;
  hyphens: none;
  margin: 0;
  text-wrap: balance;
}

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.skip {
  position: absolute; left: -999px; top: 0; z-index: 50;
  background: var(--accent); color: var(--accent-ink);
  padding: 0.75rem 1.25rem; font-size: var(--step-small);
}
.skip:focus { left: 0; }

:where(a, button, select, input):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* 01 — header */

/* The utility bar is the teal field, like the footer, so the page opens and
   closes on the same colour. */
.utility {
  background: var(--accent);
  color: var(--on-dark);
  font-size: var(--step-small);
}
.utility__row {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 0.25rem 2rem;
  padding-block: 0.6rem;
}
.utility__links { display: flex; align-items: center; gap: 1.5rem; }
.utility a { text-decoration: none; }
.utility a:hover { text-decoration: underline; text-underline-offset: 0.25em; }
/* Get a Quote moved up here when the nav split in two: paper on teal. */
.utility .utility__cta {
  background: var(--on-dark);
  color: var(--ink);
  font-weight: 600;
  padding: 0.3rem 0.9rem;
  margin-block: -0.3rem;
}
.utility .utility__cta:hover { background: var(--surface); text-decoration: none; }

/* Two halves around a centred logo: the Sign Shop on the left, the
   Electrical Store on the right, mirrored, as the two panels below are. */
.nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-areas: "signs logo electrical";
  align-items: center;
  gap: 1rem clamp(1.5rem, 4vw, 4rem);
  padding-block: clamp(1rem, 2vw, 1.5rem);
}

/* The owner's single-colour logo (brand/logo.svg), inlined so its strokes
   take the teal through currentColor. It is drawn in strokes, so it needs
   size to stay legible: the small "ART & LIGHTING INC." line is the limit. */
.wordmark {
  grid-area: logo;
  display: block;
  color: var(--ink);
  text-decoration: none;
}
.logo {
  display: block;
  width: clamp(5rem, 3.6rem + 4vw, 7.5rem);
  height: auto;
  aspect-ratio: 1;
}

/* Both halves hang from the top, so the two section names share a line even
   when the Sign Shop's longer links wrap to a second row. */
.nav__half { align-self: start; padding-top: 0.5rem; }
.nav__half--signs { grid-area: signs; }
.nav__half--electrical { grid-area: electrical; text-align: right; }

.nav__section {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(1.75rem, 1.2rem + 1.5vw, 2.5rem);
  line-height: 0.9;
  text-decoration: none;
  margin-bottom: 0.6rem;
}
.nav__section:hover { color: var(--muted); }

.nav__sub {
  display: flex; flex-wrap: wrap;
  gap: 0.3rem clamp(1rem, 1.8vw, 1.75rem);
  list-style: none; margin: 0; padding: 0;
}
.nav__half--electrical .nav__sub { justify-content: flex-end; }
.nav__sub a {
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  text-underline-offset: 0.35em;
  text-decoration-thickness: 2px;
}
.nav__sub a:hover { text-decoration: underline; }

.nav__toggle {
  display: none;
  font: inherit; font-weight: 600;
  color: var(--ink);
  background: var(--surface);
  border: 0;
  padding: 0.7rem 1.1rem;
  cursor: pointer;
}

/* Phones and tablets: logo centred on its own row, the Menu button at the
   right, and the two halves open beneath it as two lists. */
@media (max-width: 54rem) {
  .nav {
    grid-template-columns: 1fr auto 1fr;
    grid-template-areas:
      ".     logo  toggle"
      "signs signs signs"
      "electrical electrical electrical";
    /* No row gap: the two menu rows are empty while the menu is closed. */
    row-gap: 0;
  }
  .js .nav__toggle { display: block; grid-area: toggle; justify-self: end; }
  .js .nav__half { display: none; }
  .js .nav.is-open .nav__half { display: block; }
  .nav__half--electrical { text-align: left; }
  .nav__half--electrical .nav__sub { justify-content: flex-start; }
  .nav__half { padding-top: 0.75rem; }
  .nav__sub { flex-direction: column; }
  .nav__sub a { display: block; padding-block: 0.5rem; font-size: var(--step-lead); }
  .utility__hours { display: none; }
}
@media (max-width: 30rem) {
  .utility__social { display: none; }
  .utility__row { justify-content: center; }
}

/* page title — twice as much space above as below, per the layout reference */

.page-title {
  /* Measured, not guessed: at 390px this sentence needs 28px or less to hold
     two lines, and the dealt step bottoms out at 32px. The floor drops just
     far enough for the phone and still reaches the dealt 4rem on desktop. */
  /* Measured in Big Shoulders 800: the longer line ("Custom Signs and
     Lighting") is 11.08 times the font size wide, so the size is the shell's
     inner width over 12, which keeps the authored two lines at every width
     with room for a scrollbar. 115px at 1440, 61px at 768, 30px at 390. */
  font-size: min(9rem, calc((min(100vw, var(--shell)) - 2 * var(--gutter)) / 12));
  /* With the masthead's own padding this still gives twice the space above
     as below, and it keeps the two Enter buttons on a 1440×900 first screen. */
  margin-top: clamp(1.25rem, 2.5vw, 2rem);
  margin-bottom: clamp(1.25rem, 2.5vw, 2rem);
}

/* 02 — search */

.search {
  display: flex; flex-wrap: wrap; align-items: stretch; gap: 2px;
  background: var(--bg);
  /* The search belongs to the panels it sits above, so this is an inside gap,
     not a between-sections one. The big --section-gap is kept for the places
     where two sections actually meet: panels to band, band to footer. */
  margin-bottom: clamp(2rem, 4vw, 3.5rem);
}
.search__label {
  display: flex; align-items: center;
  background: var(--surface);
  padding-inline: clamp(1rem, 2vw, 1.5rem);
  font-size: var(--step-small);
  color: var(--muted);
  white-space: nowrap;
}
.search__scope,
.search__input {
  font-family: inherit;
  font-size: var(--step-body);
  color: var(--ink);
  background: var(--surface);
  border: 0;
  padding: 1rem;
}
.search__scope { cursor: pointer; }
.search__input { flex: 1 1 16rem; min-width: 0; }
.search__input::placeholder { color: var(--muted); }
.search__go {
  font-family: inherit;
  font-size: var(--step-body);
  background: var(--surface);
  color: var(--ink);
  border: 0;
  padding: 1rem clamp(1.5rem, 3vw, 2.75rem);
  cursor: pointer;
  transition: background 180ms ease, color 180ms ease;
}
.search__go:hover { background: var(--ink); color: var(--bg); }

/* 03 — the two panels */

.panels {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px;
  background: var(--bg);
}

.panel {
  position: relative; isolation: isolate;
  display: flex;
  /* Tall entry cards (owner, 2026-10-25): close to a full screen high. */
  min-height: clamp(36rem, 88vh, 60rem);
  overflow: hidden;
}

/* Two copies of the same photograph: the room, and the same room lit.
   The lit copy is masked to a soft pool of light that follows the pointer, so
   moving across the panel walks a lamp over the sign.
   The radial mask is the one gradient allowed on this site, and only here:
   the owner asked for a soft edge because a hard circle read as a cut-out
   rather than as light (CLAUDE.md, decision 44a). */
.panel__img,
.panel__lit {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 700ms ease;
}
.panel__img {
  z-index: -3;
  filter: brightness(0.38) contrast(1.08);
}
.panel__lit {
  z-index: -2;
  filter: brightness(1.55) contrast(1.05) saturate(1.1);
  opacity: 0;
  pointer-events: none;
  -webkit-mask-image: radial-gradient(circle 20rem at var(--lit-x, 50%) var(--lit-y, 50%), #000 0%, #000 24%, transparent 100%); /* taste-skill-ignore */
  mask-image: radial-gradient(circle 20rem at var(--lit-x, 50%) var(--lit-y, 50%), #000 0%, #000 24%, transparent 100%); /* taste-skill-ignore */
  transition: transform 700ms ease, opacity 300ms ease;
}
.panel::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: rgba(16, 17, 19, 0.3);
}

@media (hover: hover) and (pointer: fine) {
  .panel:hover .panel__img,
  .panel:hover .panel__lit { transform: scale(1.03); }
  .panel:hover .panel__lit { opacity: 1; }
}

/* Keyboard users get the whole panel lit rather than a pool they cannot aim. */
.panel:focus-within .panel__lit {
  opacity: 1;
  -webkit-mask-image: none;
  mask-image: none;
}

.panel__body {
  position: relative;
  margin-top: auto;
  padding: clamp(1.75rem, 3.5vw, 3rem)
           max(var(--gutter), calc((100vw - var(--shell)) / 2 + var(--gutter)));
  max-width: 44rem;
  color: var(--on-dark);
}
/* One step under the page title, so the title stays the largest type. */
.panel__name {
  font-size: var(--step-head);
  margin-bottom: 1.25rem;
}
/* Paper-coloured, like the type it sits under: on this palette the teal
   accent is kept for the actions alone. */
.panel__rule {
  width: 4.5rem; height: 5px;
  background: var(--on-dark);
  margin-bottom: 1.25rem;
}
.panel__line {
  font-size: var(--step-lead);
  margin-bottom: 0.5rem;
}
.panel__list {
  font-size: var(--step-body);
  margin-bottom: 2rem;
}

.button {
  display: inline-block;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: var(--step-body);
  font-weight: 600;
  padding: 1rem 2.25rem;
  text-decoration: none;
  white-space: nowrap;
  transition: background 180ms ease, transform 180ms ease;
}
.button:hover { background: var(--muted); transform: translateY(-2px); }
/* On the dark photographs the teal button would sink into the picture, so
   the panel buttons invert: paper filled, teal type. */
.panel .button { background: var(--on-dark); color: var(--ink); }
.panel .button:hover { background: var(--surface); }
.button:active { transform: translateY(0); }

/* 04 — quote band */

.band {
  background: var(--surface);
  margin-top: var(--section-gap);
}
.band__row {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 1.5rem 2.5rem;
  padding-block: clamp(2.5rem, 5vw, 4rem);
}
/* Two authored lines; the longer is 10.56 times the font size, so on a
   phone the size follows the width instead of the step's 40px floor. */
.band__title {
  font-size: min(var(--step-head), calc((100vw - 2 * var(--gutter)) / 11.5));
}

/* 05 — footer */

/* The footer inverts ground and ink, as the sheet asks. */
.footer {
  background: var(--accent);
  color: var(--on-dark);
  /* Two coloured fields meet here, so they touch: a strip of paper between
     the quote band and the teal footer read as a mistake. */
  padding-top: clamp(3rem, 6vw, 5rem);
  padding-bottom: clamp(2rem, 4vw, 3rem);
}

.footer__cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: clamp(2rem, 4vw, 3.5rem);
}
.footer__col { min-width: 0; }

.footer__head {
  font-size: var(--step-lead);
  margin-bottom: 1.1rem;
}

.footer__list {
  list-style: none;
  margin: 0; padding: 0;
  display: grid; gap: 0.6rem;
}
.footer__list a,
.footer__address a {
  font-size: var(--step-body);
  text-decoration: none;
}
.footer__list a:hover,
.footer__address a:hover { text-decoration: underline; text-underline-offset: 0.25em; }

.footer__address {
  font-style: normal;
  font-size: var(--step-body);
  line-height: 1.8;
}
.footer__hours {
  font-size: var(--step-body);
  color: var(--muted);
  line-height: 1.8;
  margin-top: 1rem;
}

.footer__base {
  display: flex; flex-wrap: wrap;
  justify-content: space-between; gap: 0.5rem 2rem;
  margin-top: clamp(3rem, 6vw, 5rem);
  font-size: var(--step-small);
  color: var(--muted);
}
.footer__legal { display: flex; gap: 0.5rem; }
.footer__base a { text-decoration: none; }
.footer__base a:hover { text-decoration: underline; text-underline-offset: 0.25em; }
/* Secondary text on the teal field: the paper surface tone, not the teal muted. */
.footer .footer__hours,
.footer .footer__base { color: var(--surface); }

/* inner pages — page hero, sections, cards, steps (Sign Shop, Wireframes/02) */

.page-hero {
  padding-top: clamp(1rem, 2.5vw, 2rem);
  margin-bottom: clamp(3rem, 6vw, 5rem);
}
.crumbs ol {
  display: flex; flex-wrap: wrap; gap: 0.25rem 0;
  list-style: none; margin: 0; padding: 0;
  font-size: var(--step-small);
  color: var(--muted);
}
.crumbs li + li::before { content: "/"; margin-inline: 0.6em; }
.crumbs a { text-decoration: none; }
.crumbs a:hover { text-decoration: underline; text-underline-offset: 0.25em; }
.crumbs a[aria-current="page"] { color: var(--ink); font-weight: 600; }

/* Category and sub-category pages: the title is a heading, not a monument
   (owner, 2026-10-25). */
.page-hero--sub .page-title {
  /* Measured in Big Shoulders 800: the longest first line among the tree's
     names ("Neon Signs waterproof", "City Permit Drawings &") is about 10
     times the font size, so the size never exceeds the width over 10.5 and
     every name holds two lines. */
  font-size: min(var(--step-head), calc((100vw - 2 * var(--gutter)) / 10.5));
  max-width: 22ch;
  /* The breadcrumb belongs to the title (16px above), the lead follows it. */
  margin-top: 1rem;
  margin-bottom: 1.5rem;
}
/* Beside a picture the title has only its column, so it is sized from that. */
.detail__text { container-type: inline-size; }
.detail .page-title {
  font-size: min(var(--step-head), 9.5cqi);
  max-width: none;
}

.page-hero__lead {
  font-size: var(--step-lead);
  line-height: 1.35;
  max-width: 40ch;
  margin-bottom: 2rem;
}

.section { margin-top: var(--section-gap); }
.page-hero + .section { margin-top: 0; }

.section-title {
  font-size: var(--step-section);
  /* About 0.6 of the title size: close to its content, while the gap above
     (the section gap, 72-224px) stays at least four times larger. */
  margin-bottom: clamp(1.25rem, 0.9rem + 1.2vw, 2rem);
}

/* Cards are a photograph and words on the paper itself: no box and no
   outline, per the skill's house style. */
.cards {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(2.5rem, 4vw, 3.5rem) var(--gutter);
}
/* The card lift, the owner's choice "D — Rise and open" (CLAUDE.md, decision
   64): on hover, on a held finger or on keyboard focus the card rises off the
   page as a sheet of paper, and its photo opens slowly inside its frame.
   The skill bans hover lifts and shadows; the owner chose this one for cards
   only. At rest the sheet is invisible: it is the page colour with no shadow,
   padded and pulled back by the same amount so the grid does not move. */
:root {
  --lift-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --lift-t: 650ms;
  --lift-shadow: 0 1px 2px rgba(6, 82, 92, 0.06), 0 8px 16px rgba(6, 82, 92, 0.08), 0 24px 48px rgba(6, 82, 92, 0.12); /* taste-skill-ignore */
}
.card {
  min-width: 0;
  position: relative;
  margin: -0.75rem;
  padding: 0.75rem;
  transition: transform var(--lift-t) var(--lift-ease), box-shadow var(--lift-t) var(--lift-ease);
}
.card__link { display: block; text-decoration: none; -webkit-tap-highlight-color: transparent; }
.card__media {
  display: block;
  overflow: hidden;
  background: var(--surface);
  margin-bottom: 1.1rem;
}
.card__img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  transition: transform 1100ms var(--lift-ease);
}
.card.is-up,
.card:focus-within {
  background: var(--bg);
  transform: translateY(-10px);
  box-shadow: var(--lift-shadow); /* taste-skill-ignore */
}
.card.is-up .card__img,
.card:focus-within .card__img { transform: scale(1.05); }
@media (hover: hover) and (pointer: fine) {
  .card:hover {
    background: var(--bg);
    transform: translateY(-10px);
    box-shadow: var(--lift-shadow); /* taste-skill-ignore */
  }
  .card:hover .card__img { transform: scale(1.05); }
}
/* Which branch of the tree a sign type sits in, under its name: the same
   name exists under Storefront Signs and Interior Signs (docs/SITEMAP.md). */
.card__parent {
  display: block;
  font-size: var(--step-small);
  font-weight: 600;
  color: var(--muted);
  margin: -0.4rem 0 0.75rem;
}
/* Card names are sized from the card's own width: the longest first line
   among the tree's names is about 10 times the font size, so 9.5% of the
   card keeps every name to two lines, four cards to a row or one. */
.card__link { container-type: inline-size; }
.card__name {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: min(2.25rem, 9.5cqi);
  line-height: 0.92;
  letter-spacing: -0.005em;
  text-wrap: balance;
  margin: 0 0 0.9rem;
}
.card__text { max-width: 34ch; margin-bottom: 1rem; }
.card__go {
  display: inline-block;
  font-weight: 600;
  text-decoration: none;
  text-underline-offset: 0.3em;
  text-decoration-thickness: 2px;
}
.card__go:hover { text-decoration: underline; }

/* How it works: an ordered list, so the order is carried by position; the
   wireframe's numbered circles become the same thick bar the home panels use. */
.steps {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(2.5rem, 4vw, 3.5rem) var(--gutter);
}
.steps__item::before {
  content: "";
  display: block;
  width: 4.5rem; height: 5px;
  background: var(--accent);
  margin-bottom: 1.25rem;
}
.steps__name {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  /* Below the section title it belongs to. */
  font-size: clamp(1.5rem, 1.15rem + 1.1vw, 2.25rem);
  line-height: 0.9;
  margin: 0 0 0.9rem;
}
.steps__item p { max-width: 30ch; }

/* Gallery (owner's choice "A — Gallery Grid with Lightbox", 21st.dev):
   landscape tiles, four columns by three rows on a page, two by three on a
   phone; every tile opens the photo viewer. Tiles share the card lift. */
.gallery {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--gutter);
}
.tile {
  display: block; width: 100%;
  padding: 0; border: 0; background: none;
  cursor: zoom-in;
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--lift-t) var(--lift-ease), box-shadow var(--lift-t) var(--lift-ease);
}
.tile__media {
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--surface);
}
.tile__img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1100ms var(--lift-ease);
}
.tile.is-up,
.tile:focus-visible {
  transform: translateY(-6px);
  box-shadow: var(--lift-shadow); /* taste-skill-ignore */
}
.tile.is-up .tile__img,
.tile:focus-visible .tile__img { transform: scale(1.05); }
@media (hover: hover) and (pointer: fine) {
  .tile:hover {
    transform: translateY(-6px);
    box-shadow: var(--lift-shadow); /* taste-skill-ignore */
  }
  .tile:hover .tile__img { transform: scale(1.05); }
}

/* The section's title on the left, the way to the full gallery on the right. */
.gallery__head {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  justify-content: space-between;
  gap: 1rem 2rem;
  margin-bottom: clamp(1.25rem, 0.9rem + 1.2vw, 2rem);
}
.gallery__head .section-title { margin-bottom: 0; }
.gallery__more {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 1rem 1.5rem;
}
.gallery__more p { max-width: 30ch; }
/* With 7 to 12 photos a desktop already shows them all; only a phone, which
   shows 6, needs the way to the rest. */
@media (min-width: 40.0625rem) {
  .gallery__more--phone { display: none; }
}

.button--quiet { background: var(--surface); color: var(--ink); white-space: normal; }

/* Main gallery: the wireframe's filters, then the grid, then more on demand. */
.filters {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  margin-top: 2rem;
}
.filters[hidden] { display: none; }
/* The second step: the chosen category's sign types, smaller and close under
   the first row so it reads as part of it. */
.filters--sub { margin-top: 0.75rem; gap: 0.4rem; }
.filters--sub .filter { padding: 0.5rem 0.95rem; font-size: var(--step-small); }
.filter {
  font: inherit; font-weight: 600;
  color: var(--ink);
  background: var(--surface);
  border: 0;
  padding: 0.7rem 1.4rem;
  cursor: pointer;
  transition: background var(--t-hover, 180ms) ease, color var(--t-hover, 180ms) ease;
}
.filter:hover { text-decoration: underline; text-underline-offset: 0.25em; }
.filter[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.gallery [hidden] { display: none; }
.gallery__paging { display: flex; justify-content: center; margin-top: clamp(2rem, 4vw, 3rem); }
.gallery__paging [hidden] { display: none; }

.empty {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 1.5rem 2.5rem;
  background: var(--surface);
  padding: clamp(1.75rem, 4vw, 3rem);
}
.empty__text { font-size: var(--step-lead); line-height: 1.35; max-width: 40ch; }

/* The viewer's caption: which sign type the photo shows, linked to its page. */
.lightbox__caption { margin-right: auto; }
.lightbox__caption a { color: inherit; text-underline-offset: 0.25em; }
.lightbox__caption:empty { display: none; }
.button--quiet:hover { background: var(--surface); }

@media (max-width: 40rem) {
  .gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* On a phone the page shows two columns by three rows. */
  .gallery--preview li:nth-child(n + 7) { display: none; }
}

/* Photo viewer: one photo at a time on the teal field, with previous, next
   and close; arrow keys, Escape and a sideways swipe work too. */
.lightbox {
  position: fixed; inset: 0; z-index: 100;
  display: grid;
  /* minmax(0, 1fr): without it the photo's own width sizes the column and
     pushes the viewer wider than the screen. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr) auto;
  background: var(--accent);
  color: var(--on-dark);
  padding: clamp(0.75rem, 2vw, 1.5rem);
}
.lightbox[hidden] { display: none; }
.lightbox__bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
}
.lightbox__count { font-weight: 600; font-variant-numeric: tabular-nums; }
.lightbox__stage {
  display: grid; place-items: center;
  min-height: 0; min-width: 0;
  padding-block: 1rem;
}
.lightbox__frame {
  /* Leaves room for the top bar, the buttons and the padding (about 12rem). */
  width: min(100%, calc((100dvh - 12rem) * 4 / 3));
  aspect-ratio: 4 / 3;
  background: var(--surface);
  overflow: hidden;
}
.lightbox__frame img { width: 100%; height: 100%; object-fit: contain; background: var(--ink); }
.lightbox__nav { display: flex; justify-content: center; gap: 0.75rem; }
.lightbox button {
  font: inherit; font-weight: 600;
  color: var(--ink);
  background: var(--on-dark);
  border: 0;
  padding: 0.75rem 1.4rem;
  cursor: pointer;
}
.lightbox button:hover { background: var(--surface); }
.lightbox :focus-visible { outline-color: var(--on-dark); }
html.has-lightbox { overflow: hidden; }

/* Get a Quote (Wireframes/06): the form beside "Prefer to talk?". Fields are
   tone steps on the paper, never outlined boxes (the skill's house style);
   the palette has no red, so an error is a thick ink bar and bold words. */
/* Owner choice "د" (21st.dev "Project Inquiry Form"): the form in a card on
   the left (owner, 2026-10-25), "Prefer to talk?" on the right; on a phone the
   form comes first. */
.quote {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: clamp(2.5rem, 5vw, 5rem);
  align-items: start;
  margin-bottom: var(--section-gap);
}
.quote__note { font-size: var(--step-small); color: var(--muted); margin-bottom: 1.25rem; }
.quote__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem;
}
.field { min-width: 0; margin: 0; padding: 0; border: 0; }
.field--wide, .field--choice, .field--size { grid-column: 1 / -1; }
.field[hidden] { display: none; }
.field__label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.5rem;
  padding: 0;
}
.field__req { color: var(--muted); }
.field__input {
  width: 100%;
  min-height: 3rem;
  font: inherit;
  color: var(--ink);
  background: var(--surface);
  border: 0;
  border-bottom: 3px solid transparent;
  border-radius: 0;
  padding: 0.75rem 1rem;
}
.field__input::placeholder { color: var(--muted); opacity: 1; }
.field__input:focus { border-bottom-color: var(--accent); outline: none; }
.field__input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
textarea.field__input { resize: vertical; min-height: 9rem; }
.field__hint { font-size: var(--step-small); color: var(--muted); margin-top: 0.4rem; }
.field__error { font-size: var(--step-small); font-weight: 600; margin-top: 0.4rem; }
.field__error[hidden] { display: none; }
.field.is-invalid .field__input,
.field.is-invalid .choice__item { border-bottom-color: var(--ink); }

/* Radio choices as a row of buttons; the radio itself stays for keyboards
   and screen readers. */
.choice { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.choice__item {
  position: relative;
  display: inline-flex; align-items: center;
  min-height: 3rem;
  padding: 0.7rem 1.2rem;
  font-weight: 600;
  background: var(--surface);
  border-bottom: 3px solid transparent;
  cursor: pointer;
}
.choice__item input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.choice__item:has(input:checked) { background: var(--accent); color: var(--accent-ink); }
.choice__item:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

.size { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr) 6rem; align-items: center; gap: 0.75rem; }

.files__list { display: grid; gap: 0.5rem; margin-bottom: 0.75rem; }
.files__row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; background: var(--surface); padding: 0.5rem; }
/* The browser's own file button does not match the site, so the input is
   hidden behind a styled "Choose a file" label it still belongs to. */
.files__pick { position: relative; display: inline-flex; align-items: center; min-height: 2.75rem; padding: 0.65rem 1rem; background: var(--accent); color: var(--accent-ink); font-weight: 600; cursor: pointer; }
.files__pick input { position: absolute; inset: 0; opacity: 0; width: 100%; cursor: pointer; }
.files__pick:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.files__name { flex: 1; min-width: 0; font-size: var(--step-small); color: var(--muted); overflow-wrap: anywhere; }
.files__list:has(> :only-child) .files__remove { display: none; }
.files__remove, .files__add {
  font: inherit; font-weight: 600;
  color: var(--ink);
  background: var(--surface);
  border: 0;
  padding: 0.65rem 1rem;
  min-height: 2.75rem;
  cursor: pointer;
}
.files__remove { background: var(--bg); }
.files__add:hover, .files__remove:hover { text-decoration: underline; text-underline-offset: 0.25em; }
.files__add[hidden] { display: none; }

.quote__privacy { font-size: var(--step-small); color: var(--muted); margin: 2rem 0 1rem; }
.quote__privacy a { color: var(--ink); }
.quote__done { background: var(--surface); padding: clamp(1.5rem, 3vw, 2.5rem); }
.quote__done[hidden] { display: none; }
.quote__done:focus { outline: none; }
.quote__done p { font-size: var(--step-lead); line-height: 1.35; max-width: 40ch; }
.quote.is-sent .quote__grid,
.quote.is-sent .quote__note,
.quote.is-sent .quote__privacy,
.quote.is-sent .quote__send { display: none; }

.quote__aside-title { font-size: var(--step-section); margin-bottom: 1.5rem; }
.talk { margin: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem 2rem; }
/* Call and WhatsApp share a row; the address and the hours need the width. */
.talk > div:nth-child(n + 3) { grid-column: 1 / -1; }

/* The form card: a tone step up from the paper, its fields back on paper. */
.quote__form { background: var(--surface); padding: clamp(1.5rem, 3.5vw, 2.75rem); }
.quote__form .field__input,
.quote__form .choice__item,
.quote__form .files__row,
.quote__form .files__add { background: var(--bg); }
.quote__form .choice__item:has(input:checked) { background: var(--accent); }
.quote__form .files__remove { background: var(--surface); }
.quote__done { background: var(--bg); }

/* Five-star Google reviews in the column beside the form, under the contact
   details, moving slowly from top to bottom (owner, 2026-10-25). The column
   stretches to the form's height and the reviews fill what is left of it.
   The set is in the page twice, so moving it by half a track loops. */
.quote { align-items: stretch; }
.quote__aside { display: flex; flex-direction: column; }
.strip {
  flex: 1;
  display: flex; flex-direction: column;
  min-height: 22rem;
  margin-top: clamp(2rem, 4vw, 3rem);
  background: var(--surface);
  padding: clamp(1.25rem, 2.5vw, 1.75rem);
}
.strip__head {
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: 0.5rem 1.5rem;
  margin-bottom: 1.25rem;
}
.strip__title { font-size: var(--step-lead); line-height: 1.1; }
/* The window takes whatever height is left and clips the moving list. */
.strip__window { position: relative; flex: 1; min-height: 0; overflow: hidden; }
.strip__window:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.strip__track { list-style: none; margin: 0; padding: 0; position: absolute; inset: 0 0 auto; }
.strip__item {
  /* Space under every item, not a gap: the track is then two equal halves
     and the loop has no jump. */
  padding-bottom: 1.75rem;
}
.strip__by { display: flex; align-items: center; gap: 0.65rem; margin-bottom: 0.5rem; }
.strip__text {
  line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
  overflow: hidden;
}
@media (prefers-reduced-motion: no-preference) {
  .strip__track { animation: strip-down 45s linear infinite; }
  .strip__window:hover .strip__track,
  .strip__window:focus-within .strip__track { animation-play-state: paused; }
}
/* Top to bottom: the list starts half a track up and slides down to rest. */
@keyframes strip-down { from { transform: translateY(-50%); } to { transform: translateY(0); } }
/* Without motion the reviews are a list the visitor scrolls. */
@media (prefers-reduced-motion: reduce) {
  .strip__window { overflow-y: auto; }
  .strip__track { position: static; }
}
@media (max-width: 54rem) {
  /* Under the form on a phone: no panel, so the words sit on the page margins. */
  .strip { flex: none; min-height: 0; background: none; padding: 0; }
  .strip__window { flex: none; height: 24rem; }
}

.review__avatar {
  position: relative; flex: none;
  width: 2.5rem; height: 2.5rem;
  border-radius: 50%;
  overflow: hidden;
  display: grid; place-items: center;
  background: var(--accent); color: var(--accent-ink);
  font-weight: 600;
}
/* The reviewer's initial sits under the photo and shows if it fails to load. */
.review__avatar::before { content: attr(data-initial); }
.review__avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.review__who { display: grid; gap: 0.1rem; }
.review__name { font-weight: 600; }
.review__stars { display: inline-flex; gap: 0.1rem; color: var(--accent); }
.talk dt { font-size: var(--step-small); font-weight: 600; color: var(--muted); }
.talk dd { margin: 0.2rem 0 0; font-size: var(--step-lead); line-height: 1.35; }
.talk a { text-underline-offset: 0.2em; }

@media (max-width: 54rem) {
  .quote { grid-template-columns: 1fr; }
}
@media (max-width: 40rem) {
  .quote__grid { grid-template-columns: 1fr; }
  .size { grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); }
  .size__unit { grid-column: 1 / -1; }
}

/* Quote page at form scale (owner, 2026-10-25: the sizes were too big; every
   text was 19px and fields 56px tall). Standard form sizes: 15px labels, 16px
   field text (16px also stops phones zooming into a field), 44px fields and
   buttons, 17px contact details, a smaller side heading and tighter spacing.
   The page title and lead keep the site's sizes. */
.quote { font-size: 1rem; }
.quote__grid { gap: 1.1rem 1.25rem; }
.quote__form { padding: clamp(1.25rem, 2.5vw, 2rem); }
.quote .field__label { font-size: 0.9375rem; margin-bottom: 0.35rem; }
.quote .field__input { font-size: 1rem; min-height: 2.75rem; padding: 0.55rem 0.85rem; }
.quote textarea.field__input { min-height: 7.5rem; }
.quote .choice__item { font-size: 0.9375rem; min-height: 2.75rem; padding: 0.5rem 1rem; }
.quote .files__pick, .quote .files__add, .quote .files__remove { font-size: 0.9375rem; min-height: 2.5rem; padding: 0.5rem 0.9rem; }
.quote .quote__send { font-size: 1rem; padding: 0.8rem 1.75rem; }
.quote__privacy { margin: 1.5rem 0 0.9rem; max-width: 60ch; }
.quote__done p { font-size: 1rem; }
.quote__aside-title { font-size: clamp(1.5rem, 1.2rem + 0.8vw, 2rem); margin-bottom: 1.1rem; }
.talk { gap: 1.1rem 1.5rem; }
.talk dt { font-size: var(--step-small); }
.talk dd { font-size: 1rem; }
.strip__title { font-size: 1rem; font-family: var(--font-text); text-transform: none; font-weight: 600; letter-spacing: 0; }
.strip__text { font-size: 1rem; max-width: 62ch; }
.review__name { font-size: 0.9375rem; }

/* ---- Info pages: About, FAQ, Contact, Privacy, Terms (Wireframes 07-12) */

/* A plain note on anything that is a sample until the owner confirms it. */
.sample-note {
  display: inline-block;
  max-width: 62ch;
  font-size: 1rem;
  color: var(--ink);
  border-left: 4px solid var(--accent);
  padding: 0.35rem 0 0.35rem 0.75rem;
  margin-top: 1.25rem;
}
.sample-note + .products { margin-top: clamp(1.25rem, 2vw, 2rem); }

/* About: the story beside the photo. */
.about-story {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
.about-story__media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.about-story__text p { max-width: 58ch; }
.about-story__text p + p { margin-top: 1rem; }

/* About: the figures, set large in the display face, no boxes. */
.stats {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--gutter);
}
.stats__item { display: grid; gap: 0.35rem; }
.stats__item::before { content: ""; width: 3rem; height: 5px; background: var(--accent); margin-bottom: 0.75rem; }
.stats__value {
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  font-size: clamp(2rem, 1.4rem + 2vw, 3.25rem); line-height: 0.9;
}
.stats__label { color: var(--muted); }

/* About: values as words under the thick bar (no icon circles). */
.values {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 4vw, 3.5rem) var(--gutter);
}
.values__name {
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  font-size: clamp(1.5rem, 1.15rem + 1.1vw, 2.25rem); line-height: 0.9;
  margin: 0 0 0.75rem;
}
.values__item p { max-width: 34ch; }

/* FAQ: a search field, then the questions as an accordion. */
.faq-search { margin-top: 1.75rem; max-width: 36rem; }
.faq-search .field__input { min-height: 3rem; }
.faq {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 20rem);
  gap: clamp(2rem, 4vw, 4rem); align-items: start;
  margin-bottom: var(--section-gap);
}
.faq__list { display: grid; gap: 0.5rem; }
.faq__none { grid-column: 1; }
/* Beside the questions: the ways to ask us directly, staying in view. */
.faq__help { grid-column: 2; grid-row: 1 / span 2; position: sticky; top: 1.5rem; background: var(--accent); color: var(--on-dark); padding: clamp(1.25rem, 2.5vw, 1.75rem); }
.faq__help-title { font-size: clamp(1.5rem, 1.2rem + 0.8vw, 2rem); margin-bottom: 0.6rem; }
.faq__help-list { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: 0.6rem; }
.faq__help a { color: var(--on-dark); font-weight: 600; text-underline-offset: 0.2em; }
.faq__item { background: var(--surface); }
.faq__item[hidden] { display: none; }
.faq__q {
  display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  padding: 1.1rem 1.25rem;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after { content: "+"; font-size: 1.5rem; line-height: 1; font-weight: 400; }
.faq__item[open] .faq__q::after { content: "\2212"; }
.faq__q:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.faq__a { padding: 0 1.25rem 1.25rem; }
.faq__a p { max-width: 62ch; }
.faq__none { margin-top: 1rem; }
.faq__none[hidden] { display: none; }

/* Contact: three tone-step blocks, then the map beside the message form. */
.contact-cards {
  list-style: none; margin: 0 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gutter);
}
.contact-cards__item { background: var(--surface); padding: clamp(1.25rem, 2.5vw, 1.75rem); }
.contact-cards__title { font-size: var(--step-small); font-family: var(--font-text); text-transform: none; letter-spacing: 0; font-weight: 600; color: var(--muted); margin-bottom: 0.4rem; line-height: 1.3; }
.contact-cards__item p { font-size: 1.0625rem; line-height: 1.45; }
.contact {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: stretch;
  margin-bottom: var(--section-gap);
  font-size: 1rem;
}
.map {
  display: flex; flex-direction: column; justify-content: center; align-items: flex-start;
  gap: 0.9rem;
  min-height: 24rem;
  background: var(--surface);
  padding: clamp(1.5rem, 3vw, 2.5rem);
}
.map__text { font-size: var(--step-lead); line-height: 1.3; }
.map__note { font-size: var(--step-small); color: var(--muted); }
.map iframe { width: 100%; height: 100%; min-height: 24rem; border: 0; display: block; }
.map.is-loaded { padding: 0; display: block; }
.contact__title { font-size: clamp(1.5rem, 1.2rem + 0.8vw, 2rem); margin-bottom: 1.1rem; }
.contact .field__label { font-size: 0.9375rem; margin-bottom: 0.35rem; }
.contact .field__input { font-size: 1rem; min-height: 2.75rem; padding: 0.55rem 0.85rem; }
.contact textarea.field__input { min-height: 8rem; }
.contact .quote__send { font-size: 1rem; padding: 0.8rem 1.75rem; }
.contact.is-sent .quote__grid,
.contact.is-sent .quote__privacy,
.contact.is-sent .quote__send { display: none; }

/* Privacy and Terms: contents on the left, staying in view, text beside it. */
.legal {
  display: grid; grid-template-columns: minmax(0, 16rem) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
  margin-bottom: var(--section-gap);
}
.legal__toc { position: sticky; top: 1.5rem; background: var(--surface); padding: 1.25rem 1.5rem; }
.legal__toc-title { font-size: var(--step-small); font-family: var(--font-text); text-transform: none; letter-spacing: 0; font-weight: 600; margin-bottom: 0.75rem; line-height: 1.3; }
.legal__toc ol { margin: 0; padding-left: 1.1rem; display: grid; gap: 0.5rem; font-size: 0.9375rem; }
.legal__toc a { text-decoration: none; }
.legal__toc a:hover { text-decoration: underline; text-underline-offset: 0.2em; }
.legal__text { max-width: 44rem; }
.legal__text .sample-note { margin: 0 0 2rem; }
.legal__section { scroll-margin-top: 1.5rem; }
.legal__section + .legal__section { margin-top: 2.25rem; }
.legal__title { font-size: var(--step-section); margin-bottom: 0.75rem; }
.legal__section p { max-width: 62ch; }

@media (max-width: 54rem) {
  .about-story, .contact, .legal, .faq { grid-template-columns: 1fr; }
  .faq__help { grid-column: auto; grid-row: auto; position: static; }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .values, .contact-cards { grid-template-columns: 1fr; }
  .legal__toc { position: static; }
}

/* Stand-in for a photo not uploaded yet: a plain frame in the surface tone. */
.card__media--empty { aspect-ratio: 4 / 5; }

/* Sub-category page: the words beside the picture. */
.detail {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}
.detail__intro { max-width: 52ch; margin-bottom: 2rem; }
.detail .page-hero__lead { margin-bottom: 1rem; }
/* On a detail page the next block is a section of its own, so it gets the
   same gap as every other section (on a category page the cards continue
   the hero and stay closer). */
.page-hero:has(.detail) { margin-bottom: var(--section-gap); }
/* Landscape, like the galleries: a portrait picture ran ~270px below the
   words beside it and left a hole under them. */
.detail__media .card__media { margin-bottom: 0; aspect-ratio: 4 / 3; }
.detail__media .card__img { aspect-ratio: 4 / 3; height: 100%; }

/* What's included: short lines, each led by the thick bar used elsewhere. */
.included {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  gap: 1.25rem;
  max-width: 48rem;
}
.included li {
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  align-items: baseline;
  gap: 1rem;
  font-size: var(--step-lead);
  line-height: 1.35;
}
.included li::before {
  content: "";
  height: 5px;
  background: var(--accent);
  align-self: center;
}

@media (max-width: 54rem) {
  .detail { grid-template-columns: 1fr; }
  .detail__media { max-width: 28rem; }
}

.band--centre .band__row {
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
}

/* Card size never changes: four to a row on desktop, two on a tablet, one on
   a phone (owner, 2026-10-25: three, two or one card grew too big). Whatever
   the count, the last row is closed by the quote card, which takes the cells
   left over: three when one card sits on the last row, two when two do, one
   when three do, and it is hidden when the row is already full. The CSS reads
   the count itself, so cards added or removed in the dashboard need nothing. */
.card--cta {
  margin: 0;
  padding: clamp(1.25rem, 2vw, 1.75rem);
  display: flex; flex-direction: column; justify-content: flex-end;
  gap: 0.9rem;
  background: var(--accent);
  color: var(--on-dark);
}
.card--cta .card__name { font-size: min(2.25rem, 9.5cqi); margin: 0; }
.card--cta p { max-width: 30ch; }
.card--cta .card__go { color: var(--on-dark); }
/* It lifts like the other cards but keeps its teal. */
.card.card--cta:hover, .card.card--cta.is-up, .card.card--cta:focus-within { background: var(--accent); }
.card--cta { container-type: inline-size; }
.cards > .card--cta:nth-child(4n + 1) { display: none; }
.cards > .card--cta:nth-child(4n + 2) { grid-column: span 3; }
.cards > .card--cta:nth-child(4n + 3) { grid-column: span 2; }

@media (max-width: 64rem) {
  .cards, .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cards > .card--cta:nth-child(n) { display: flex; grid-column: auto; }
  .cards > .card--cta:nth-child(odd) { display: none; }
}
@media (max-width: 34rem) {
  .cards, .steps { grid-template-columns: 1fr; }
  /* One to a row leaves no gap; the quote band below the list says the same. */
  .cards > .card--cta:nth-child(n) { display: none; }
}

/* motion
   The first screen arrives on the skill's load sequence (references/motion.md,
   "Load sequence in 1.2 seconds"): CSS only, started without waiting for the
   load event, settled by 1.2s, and nothing in the navigation moves. Entrances
   use the `translate` property, not `transform`, so their fill never locks
   out the hover lift on the buttons. The panel photographs are left alone:
   the light effect lives on them. Everything below the fold reveals on scroll. */

:root {
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.76, 0, 0.24, 1);
}

/* The mask the headline rises through; padded so descenders are not clipped. */
.page-title__mask {
  display: block;
  overflow: clip;
  padding-block: 0.1em 0.22em;
  margin-block: -0.1em -0.22em;
}
.page-title__text { display: block; }

@media (prefers-reduced-motion: no-preference) {
  .js .page-title__text {
    translate: 0 110%;
    animation: load-line 800ms var(--ease-expo) 100ms forwards;
  }
  .js .search {
    opacity: 0; translate: 0 12px;
    animation: load-rise 500ms var(--ease-out) 300ms forwards;
  }
  /* Inner pages: the words under the title rise after it, and the picture
     opens beside them, on the same 1.2-second sequence. */
  .js .page-hero .crumbs,
  .js .page-hero .page-hero__lead,
  .js .page-hero .detail__intro,
  .js .page-hero .button {
    opacity: 0; translate: 0 12px;
    animation: load-rise 500ms var(--ease-out) forwards;
  }
  .js .page-hero .crumbs { animation-delay: 50ms; }
  .js .page-hero .page-hero__lead { animation-delay: 300ms; }
  .js .page-hero .detail__intro { animation-delay: 380ms; }
  .js .page-hero .button { animation-delay: 460ms; }
  .js .quote__form, .js .quote__aside {
    opacity: 0; translate: 0 12px;
    animation: load-rise 600ms var(--ease-out) forwards;
  }
  .js .quote__form { animation-delay: 420ms; }
  .js .quote__aside { animation-delay: 520ms; }
  .js .detail__media {
    clip-path: inset(0 0 100% 0);
    animation: load-open 1000ms var(--ease-in-out) 150ms forwards;
  }
  .js .panel {
    clip-path: inset(0 0 100% 0);
    animation: load-open 1000ms var(--ease-in-out) 150ms forwards;
  }
  .js .panel__body > * {
    opacity: 0; translate: 0 12px;
    animation: load-rise 500ms var(--ease-out) forwards;
    animation-delay: calc(420ms + var(--n, 0) * 50ms);
  }
  .js .panel__body > :nth-child(2) { --n: 1; }
  .js .panel__body > :nth-child(3) { --n: 2; }
  .js .panel__body > :nth-child(4) { --n: 3; }
  .js .panel__body > :nth-child(5) { --n: 4; }
  .js .panel + .panel .panel__body > * {
    animation-delay: calc(480ms + var(--n, 0) * 50ms);
  }
}
@keyframes load-line { to { translate: none; } }
@keyframes load-rise { to { opacity: 1; translate: none; } }
@keyframes load-open { to { clip-path: inset(0); } }

/* The scroll reveal moves the `translate` property, not `transform`, so it
   never fights the card lift; revealed cards keep their own lift transition. */
.reveal { opacity: 0; translate: 0 1rem; }
.reveal.is-in {
  opacity: 1; translate: none;
  transition: opacity 550ms ease, translate 550ms ease;
}
.card.reveal.is-in {
  transition: opacity 550ms ease, translate 550ms ease,
              transform var(--lift-t) var(--lift-ease), box-shadow var(--lift-t) var(--lift-ease);
}

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal.is-in { opacity: 1; translate: none; transition: none; }
  .card, .card.reveal.is-in, .card__img, .tile, .tile__img { transition: none; }
  .tile:hover, .tile.is-up, .tile:focus-visible,
  .tile:hover .tile__img, .tile.is-up .tile__img, .tile:focus-visible .tile__img { transform: none; }
  .card:hover, .card.is-up, .card:focus-within { transform: none; }
  .card:hover .card__img, .card.is-up .card__img, .card:focus-within .card__img { transform: none; }
  .panel__img, .panel__lit, .button, .search__go { transition: none; }
  .panel:hover .panel__img,
  .panel:hover .panel__lit { transform: none; }
  .panel:hover .panel__lit { opacity: 1; }
  .button:hover { transform: none; }
}

/* narrow */

@media (max-width: 54rem) {
  .panels { grid-template-columns: 1fr; }
  .panel { min-height: clamp(32rem, 78svh, 44rem); }
}

@media (max-width: 40rem) {
  .search { display: grid; grid-template-columns: auto 1fr; }
  .search__scope { width: 100%; }
  .search__input,
  .search__go { grid-column: 1 / -1; }
  .search__go { text-align: center; }
  .band__row { align-items: flex-start; }
  .button { width: 100%; text-align: center; }
}

/* Contact bar — phones only. Fixed to the foot of the screen so calling,
   WhatsApp and the quote form are one tap away at any scroll depth. It is
   the teal field with paper type, the quote cell inverted to stand out.
   It waits until the teal utility bar at the top, which holds the same
   three links, has scrolled out of sight, so the first screen is not
   covered. It slides away while a form field has focus (the keyboard is
   open) and while the photo viewer is open. The footer is padded by the bar's height
   so its last line is never hidden underneath. */
.callbar { display: none; }
@media (max-width: 40rem) {
  .callbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
    display: grid; grid-template-columns: 1fr 1fr 1.3fr;
    background: var(--accent);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    transition: translate 250ms cubic-bezier(0.22, 1, 0.36, 1), visibility 0s;
  }
  .callbar__link {
    display: flex; align-items: center; justify-content: center;
    min-height: 3.5rem;
    color: var(--on-dark);
    font-size: 1rem; font-weight: 600;
    text-decoration: none;
  }
  .callbar__link--quote { background: var(--on-dark); color: var(--ink); }
  .callbar__link:focus-visible { outline: 2px solid var(--on-dark); outline-offset: -5px; }
  .callbar__link--quote:focus-visible { outline-color: var(--ink); }
  /* Hidden: moved off screen, and out of the tab order once it has gone. */
  .js:not(.has-callbar) .callbar,
  .has-field-focus .callbar,
  .has-consent .callbar,
  .has-lightbox .callbar {
    translate: 0 calc(100% + 1px);
    visibility: hidden;
    transition: translate 250ms cubic-bezier(0.22, 1, 0.36, 1), visibility 0s 250ms;
  }
  .footer { padding-bottom: calc(clamp(2rem, 4vw, 3rem) + 3.5rem + env(safe-area-inset-bottom, 0px)); }
}
@media (max-width: 40rem) and (prefers-reduced-motion: reduce) {
  .callbar { transition: none; }
}

/* Electrical Store (Wireframes/03) — the two category panels side by side,
   each a tone-step field holding every sub-category as a paper tile, in the
   sitemap's order, with "View all" at its foot. Tiles are tone, not outline
   (the skill bans outlined boxes). */
.store-intro { max-width: 40rem; margin-top: 0.5rem; }
.store-panels {
  display: grid; grid-template-columns: var(--split, 1fr 1fr);
  gap: var(--gutter); align-items: stretch;
}
.store-panel {
  display: flex; flex-direction: column; gap: clamp(1.25rem, 2vw, 1.75rem);
  background: var(--surface);
  padding: clamp(1.25rem, 3vw, 2.5rem);
}
.store-panel__title { font-size: var(--step-section); }
.store-panel__title a { text-decoration: none; }
.store-panel__title a:hover { text-decoration: underline; text-underline-offset: 0.12em; text-decoration-thickness: 0.06em; }
.store-panel__count { font-family: var(--font-text); font-size: 1rem; font-weight: 600; color: var(--muted); letter-spacing: 0; vertical-align: middle; }
.store-panel__list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr));
  gap: 0.5rem;
}
.store-panel__item {
  display: flex; align-items: flex-start; height: 100%;
  min-height: 4.25rem;
  padding: 0.75rem 0.875rem;
  background: var(--bg);
  font-size: 1rem; font-weight: 600; line-height: 1.3;
  text-decoration: none;
  transition: background 180ms ease, color 180ms ease;
}
.store-panel__item:hover { background: var(--accent); color: var(--accent-ink); }
.store-panel__item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.store-panel .card__go { margin-top: auto; }
@media (max-width: 64rem) {
  .store-panels { grid-template-columns: 1fr 1fr; }
  .store-panel__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 54rem) {
  /* Stacked, the panels need clear air between them, or the last tile of
     the first reads as a label over the second panel's title. */
  .store-panels { grid-template-columns: 1fr; row-gap: var(--section-gap); }
  .store-panel__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 40rem) {
  .store-panel__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .store-panel__item { min-height: 3.75rem; }
}
/* A sub-category with a picture: the picture square on top, the name under
   it. Product shots on white and room photos share one frame by covering it. */
.store-panel__item--photo { flex-direction: column; padding: 0; }
.store-panel__media { display: block; aspect-ratio: 1 / 1; overflow: hidden; background: var(--surface); }
.store-panel__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1100ms cubic-bezier(0.22, 1, 0.36, 1); }
.store-panel__item--photo .store-panel__name { display: block; padding: 0.75rem 0.875rem 0.875rem; }
.store-panel__item--photo:hover .store-panel__media img,
.store-panel__item--photo:focus-visible .store-panel__media img { transform: scale(1.05); }
@media (prefers-reduced-motion: reduce) {
  .store-panel__media img { transition: none; }
}
/* Stacked (tablet and phone), each panel drops its tone field and padding so
   its title and tiles sit on the page margins like every other section; the
   tiles take the tone step instead, to keep their edges. */
@media (max-width: 54rem) {
  .store-panel { background: none; padding: 0; }
  .store-panel__item { background: var(--surface); }
}

/* ---- Electrical catalogue: category / sub-category listings (Wireframes/04)
   and product pages (Wireframes/05). */

/* Product cards: the card lift of decision 64, a square picture (product
   shots are square), the name in the text face because product names are
   long and full of figures, then an optional "From" price and Get a Quote. */
.products {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(2rem, 3vw, 3rem) var(--gutter);
}
/* Listings beside the filters run five to a row on wide screens (owner,
   2026-10-31), stepping down so a card never gets too narrow to read. */
@media (max-width: 80rem) { .products { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (max-width: 72rem) { .products { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.products--four { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* The store page featured row and related products: five to a row (owner,
   2026-10-31), three on
   small laptops, two on tablets and phones. */
.products.products--five { grid-template-columns: repeat(5, minmax(0, 1fr)); }
@media (max-width: 64rem) { .products.products--five { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 54rem) { .products.products--five { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.product-card .card__img,
.product-card__img { aspect-ratio: 1 / 1; }
.product-card__name {
  font-family: var(--font-text); text-transform: none; letter-spacing: 0;
  font-size: 1.0625rem; font-weight: 600; line-height: 1.35;
  margin: 0 0 0.4rem;
}
.product-card .card__parent { margin: 0 0 0.6rem; font-size: 1rem; font-weight: 400; color: var(--ink); }
.product-card__price { font-weight: 600; margin: 0 0 0.6rem; }

.catalog__bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: clamp(1.25rem, 2.5vw, 2rem);
}
.catalog__count { font-weight: 600; margin: 0; }
.catalog__sort { display: flex; align-items: center; gap: 0.75rem; font-weight: 600; font-size: 0.9375rem; }
.catalog__sort select {
  font: inherit; font-weight: 400; color: var(--ink);
  min-height: 2.75rem; padding: 0 2.25rem 0 0.875rem;
  background: var(--surface); border: 0; border-radius: 0;
}
.catalog__body { display: grid; grid-template-columns: 15rem minmax(0, 1fr); gap: clamp(1.5rem, 3vw, 3rem); align-items: start; }
.catalog__body--nofilters { grid-template-columns: minmax(0, 1fr); }
.catalog__filters { position: sticky; top: 1.5rem; }
.catalog__filters-toggle {
  list-style: none; cursor: pointer;
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  font-size: 1.5rem; line-height: 1; margin-bottom: 1.25rem;
}
.catalog__filters-toggle::-webkit-details-marker { display: none; }
.facet { border: 0; margin: 0 0 1.5rem; padding: 0; min-width: 0; }
.facet__name { font-weight: 600; padding: 0; margin-bottom: 0.5rem; }
.facet__option { display: flex; align-items: center; gap: 0.625rem; min-height: 2.25rem; font-size: 1rem; line-height: 1.3; cursor: pointer; }
.facet__option input { width: 1.125rem; height: 1.125rem; accent-color: var(--accent); flex: none; margin: 0; }
.catalog__clear {
  font: inherit; font-weight: 600; color: var(--ink); background: none; border: 0; padding: 0;
  text-decoration: underline; text-underline-offset: 0.25em; cursor: pointer;
}
.catalog__none { margin: 1rem 0 0; }
.pager { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.5rem; margin-top: clamp(2.5rem, 4vw, 3.5rem); }
.pager[hidden] { display: none; }
.pager button {
  font: inherit; font-weight: 600; color: var(--ink);
  min-width: 2.75rem; min-height: 2.75rem; padding: 0 0.75rem;
  background: var(--surface); border: 0; cursor: pointer;
}
.pager button[aria-current="page"] { background: var(--accent); color: var(--accent-ink); }
.pager button:hover:not([aria-current]) { text-decoration: underline; text-underline-offset: 0.25em; }

.catalog-empty p { max-width: 36rem; margin: 0 0 1.5rem; }
/* A sub-category with no products yet: the message beside its picture. */
.catalog-empty--photo { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(1.5rem, 4vw, 4rem); align-items: center; }
.catalog-empty__media { aspect-ratio: 4 / 3; overflow: hidden; background: var(--surface); }
.catalog-empty__media img { width: 100%; height: 100%; object-fit: cover; }

/* Product page: picture beside the facts. The facts column stays in view
   while the picture scrolls on desktop, so Get a Quote and WhatsApp are
   always at hand (decision 43). */
.product { padding-top: clamp(1rem, 2.5vw, 2rem); }
/* A product page ends on its related products, with no band before the
   footer, so that last section keeps a section gap below it. */
.product ~ .section:last-child { padding-bottom: var(--section-gap); }
.product__main {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 4rem); align-items: start;
  margin-top: clamp(1rem, 2vw, 1.5rem);
}
.product__frame { aspect-ratio: 1 / 1; background: var(--surface); overflow: hidden; }
.product__img { width: 100%; height: 100%; object-fit: cover; }
.product__thumbs { list-style: none; margin: 0.75rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.75rem; }
.product__thumb { display: block; width: 100%; padding: 0; border: 0; background: var(--surface); cursor: pointer; opacity: 0.7; }
.product__thumb[aria-current="true"] { opacity: 1; outline: 2px solid var(--accent); outline-offset: 2px; }
.product__thumb img { aspect-ratio: 1 / 1; width: 100%; object-fit: cover; }
.product__info { position: sticky; top: 1.5rem; }
.product__kind { margin: 0 0 0.75rem; font-weight: 600; font-size: var(--step-small); }
.product__kind a { text-decoration: none; }
.product__kind a:hover { text-decoration: underline; text-underline-offset: 0.25em; }
.product__title { font-size: clamp(2rem, 1.3rem + 2.4vw, 3.5rem); line-height: 0.95; text-wrap: balance; margin: 0 0 1rem; }
.product__text { max-width: 36rem; margin: 0 0 1.25rem; }
.product__price { font-weight: 600; font-size: 1.25rem; margin: 0 0 1.25rem; }
/* Key specs set large (decision 43, the Zillow pattern), as figures over
   their labels rather than icon tiles, which the design skill bans. */
.keyspecs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; margin: 0 0 1.75rem; }
.keyspecs__item { background: var(--surface); padding: 0.875rem 1rem; display: flex; flex-direction: column-reverse; }
.keyspecs dt { font-size: var(--step-small); color: var(--muted); font-weight: 600; }
.keyspecs dd { margin: 0 0 0.2rem; font-family: var(--font-display); font-weight: 800; text-transform: uppercase; font-size: clamp(1.5rem, 1.2rem + 1vw, 2.125rem); line-height: 1; }
.product__sub { font-family: var(--font-text); text-transform: none; letter-spacing: 0; font-size: 1.0625rem; font-weight: 600; margin: 0 0 0.6rem; }
.product__features { margin: 0 0 1.75rem; padding: 0; list-style: none; }
.product__features li { position: relative; padding-left: 1.25rem; margin-bottom: 0.4rem; }
.product__features li::before { content: ""; position: absolute; left: 0; top: 0.65em; width: 0.5rem; height: 0.25rem; background: var(--accent); }
.product__actions { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
.product__actions .button { text-align: center; padding-inline: 1rem; }
.button--ghost { background: var(--surface); color: var(--ink); }
.button--ghost:hover { background: var(--surface); text-decoration: underline; text-underline-offset: 0.25em; }
.product__note { font-size: 1rem; max-width: 36rem; margin: 1rem 0 0; }

/* Every specification as label and value rows, the tone stepping every
   other row instead of rule lines. */
.specs { margin: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--gutter); }
.specs__row { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 1rem; padding: 0.75rem 1rem; }
.specs__row:nth-child(4n+1), .specs__row:nth-child(4n+2) { background: var(--surface); }
.specs dt { font-weight: 600; }
.specs dd { margin: 0; }

@media (max-width: 64rem) {
  .products { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .products--four { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 54rem) {
  .catalog__body { grid-template-columns: minmax(0, 1fr); }
  .catalog__filters { position: static; background: var(--surface); padding: 0 1rem; }
  .catalog__filters-toggle { font-size: 1.25rem; margin: 0; padding: 1rem 0; }
  .catalog__filters[open] .catalog__filters-toggle { margin-bottom: 0.5rem; }
  .catalog__filters-body { padding-bottom: 1rem; }
  .product__main { grid-template-columns: minmax(0, 1fr); }
  /* Keep the name on the first screen of a tablet: a smaller picture. */
  .product__media { width: min(100%, 26rem); }
  .catalog-empty--photo { grid-template-columns: minmax(0, 1fr); }
  .catalog-empty__media { order: -1; max-width: 32rem; }
  .product__info { position: static; }
  .specs { grid-template-columns: minmax(0, 1fr); }
  .specs__row:nth-child(4n+1), .specs__row:nth-child(4n+2) { background: none; }
  .specs__row:nth-child(odd) { background: var(--surface); }
}
@media (max-width: 40rem) {
  .products, .products--four { gap: 1.75rem 0.75rem; }
  .product-card__name { font-size: 1rem; }
  .product__actions { grid-template-columns: 1fr; }
}

/* ---- Blog (Wireframes/10) and article pages. */

/* The featured article: picture beside its title, summary and Read more. */
.post-feature {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(1.5rem, 4vw, 4rem); align-items: center;
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
}
.post-feature--last { padding-bottom: var(--section-gap); }
.post-feature__media { background: var(--surface); overflow: hidden; }
.post-feature__media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.post-feature__title { font-size: clamp(2rem, 1.3rem + 2.4vw, 3.5rem); line-height: 0.95; margin: 0 0 1.25rem; }
.post-feature__title a { text-decoration: none; }
.post-feature__title a:hover { text-decoration: underline; text-decoration-thickness: 3px; text-underline-offset: 0.12em; }
.post-feature__summary { max-width: 40ch; margin: 0 0 1rem; }
.post-feature .post-card__meta { margin-bottom: 1.5rem; }

/* Article cards, three to a row as the wireframe draws them. Titles are long
   sentences, so they are set in the text face rather than the display one. */
.posts {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 3vw, 3rem) var(--gutter);
}
.blog-grid { padding-bottom: var(--section-gap); }
.post-card__img { aspect-ratio: 4 / 3; }
.post-card__title {
  font-family: var(--font-text); font-weight: 600; text-transform: none; letter-spacing: 0;
  font-size: 1.25rem; line-height: 1.3; text-wrap: balance; margin: 0 0 0.5rem;
}
.post-card__meta { font-size: 1rem; margin: 0; }
.blog-empty { padding: clamp(1.5rem, 3vw, 2.5rem) var(--gutter) var(--section-gap); }

/* An article: title, date, picture, then the text in a column narrow
   enough to read comfortably. */
.article { padding-top: clamp(1rem, 2.5vw, 2rem); }
.article__title { font-size: clamp(2.25rem, 1.2rem + 4vw, 5rem); line-height: 0.92; max-width: 22ch; margin: 1rem 0 1.5rem; }
.article__meta { margin: 0; }
.article__figure { margin: clamp(1.5rem, 3vw, 2.5rem) 0 0; max-width: 60rem; background: var(--surface); overflow: hidden; }
.article__figure img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.article__body { max-width: 40rem; margin-top: clamp(2rem, 4vw, 3.5rem); }
.article__body p { margin: 0 0 1.25rem; }
.article__body h2 { font-size: clamp(1.625rem, 1.3rem + 1vw, 2.25rem); line-height: 0.95; margin: 2.75rem 0 1rem; }
.article__body h2:first-child { margin-top: 0; }

@media (max-width: 64rem) {
  .posts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 54rem) {
  .post-feature { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 40rem) {
  .posts { grid-template-columns: minmax(0, 1fr); }
}

/* ---- Site search results (/search/). */
.search-page { padding-bottom: var(--section-gap); }
.search-page__count { font-weight: 600; margin: 0 0 1.5rem; }
.results { list-style: none; margin: 0; padding: 0; max-width: 48rem; }
.result { margin: 0 0 2rem; }
.result__title {
  display: inline-block; font-weight: 600; font-size: 1.25rem; line-height: 1.3;
  text-decoration: none; margin-bottom: 0.25rem;
}
.result__title:hover { text-decoration: underline; text-underline-offset: 0.2em; }
.result__path { font-size: 1rem; margin: 0 0 0.25rem; }
.result__text { font-size: 1rem; margin: 0; max-width: 60ch; }
.search-page__count, .search-page__none p, .search-page noscript p { max-width: 60ch; }
.search-page__none p { margin: 0 0 1rem; }
.search-page__browse { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.75rem 2rem; }
.search-page__browse a { font-weight: 600; }

/* ---- Cookie choice (decision 27): a small teal card at the foot of the
   screen. Accept and Decline carry the same weight, so neither is pushed. */
.consent {
  position: fixed; z-index: 45; left: var(--gutter); bottom: var(--gutter);
  width: min(30rem, calc(100% - 2 * var(--gutter)));
  background: var(--accent); color: var(--on-dark);
  padding: clamp(1.25rem, 2vw, 1.75rem);
}
.consent[hidden] { display: none; }
.consent__title { font-size: 1.75rem; margin: 0 0 0.5rem; }
.consent__text { font-size: 1rem; margin: 0 0 1.25rem; }
.consent__text a { color: inherit; text-underline-offset: 0.2em; }
.consent__actions { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
.consent__button {
  font: inherit; font-size: 1rem; font-weight: 600;
  min-height: 2.75rem; padding: 0.75rem 1rem;
  background: var(--on-dark); color: var(--ink); border: 0; cursor: pointer;
}
.consent__button:hover { text-decoration: underline; text-underline-offset: 0.2em; }
.consent__button[aria-pressed="true"] { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 0.2em; }
.consent :focus-visible { outline: 2px solid var(--on-dark); outline-offset: 3px; }
.footer__cookies { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
.footer__cookies:hover { text-decoration: underline; text-underline-offset: 0.25em; }
@media (max-width: 40rem) {
  .consent { left: 0; bottom: 0; width: 100%; padding-bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px)); }
}
@media (prefers-reduced-motion: no-preference) {
  .consent:not([hidden]) { animation: consent-in 400ms var(--lift-ease) both; }
  @keyframes consent-in { from { translate: 0 1.5rem; opacity: 0; } }
}

/* ---- One-section header (owner, 2026-10-31): inside the Sign Shop or the
   Electrical Store the header carries that section alone, the logo on the
   left and the section with its categories beside it. A small link in the
   utility bar, and in the phone menu, leads to the other section. */
.nav--single {
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "logo half";
}
.nav--single .nav__half { grid-area: half; align-self: center; padding-top: 0; text-align: left; }
.nav--single .nav__sub { justify-content: flex-start; }
.utility .utility__switch { font-weight: 600; }
.nav__switch { display: none; }
@media (max-width: 54rem) {
  .nav--single {
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "logo . toggle"
      "half half half";
  }
  .nav--single .nav__half { padding-top: 0.75rem; }
  .nav__switch {
    display: inline-block; margin-top: 0.75rem; padding-block: 0.5rem;
    font-weight: 600; font-size: var(--step-lead); text-decoration: none;
  }
  .nav__switch:hover { text-decoration: underline; text-underline-offset: 0.35em; }
}
@media (max-width: 30rem) {
  .utility .utility__switch { display: none; }
}
