/* =========================================================
   Ashley & Lewis — Heritage Paint & Papers
   Stylesheet
   ========================================================= */

/* ---- Reset ---- */
*, *::before, *::after { box-sizing: border-box; }
/* Any rule setting a display value outranks the browser's own
   [hidden] { display: none }, which quietly breaks every element we
   show and hide from JavaScript. This puts that right once, globally. */
[hidden] { display: none !important; }
html, body, h1, h2, h3, h4, p, figure, ul, ol { margin: 0; padding: 0; }
ul, ol { list-style: none; }
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; border: none; background: none; color: inherit; }
input, textarea { font: inherit; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; }
}

/* ---- Design tokens ---- */
:root {
  /* Palette — grey and charcoal, matching the Ashley & Lewis roundel.
     No warm accent colour; hierarchy comes from the charcoal/graphite
     scale instead. Sage/ochre are reserved for literal paint swatches. */
  --ink:            #36454F;   /* charcoal navy, from the A&L roundel */
  --ink-soft:        #5B5E64;
  --parchment:       #F5F4F1;  /* neutral grey-paper background */
  --parchment-deep:  #E7E5E0;  /* deeper warm-grey stone for alt sections */
  --card:            #FFFFFF;
  /* The buttons carry the ink colour itself, straight off the roundel,
     rather than the graphite grey that used to sit a shade away from it.
     accent-deep is then a genuine step darker, so a hover still reads as
     a change rather than only a nudge upwards. */
  --accent:          #36454F;  /* charcoal navy — primary UI accent */
  --accent-deep:     #2A363E;  /* a shade darker, for hover and active */
  --accent-tint:     #E7E7E4;  /* pale grey wash for badges/backgrounds */
  --duckegg:         #AEC6CD;  /* the shopfront blue, used sparingly */
  --duckegg-deep:    #6F919C;
  --sage:            #7C8A5E;  /* reserved for paint-swatch colour only */
  --ochre:           #C1902F;  /* reserved for paint-swatch colour only */
  --line:            rgba(54,69,79,0.14);
  --shadow: 0 20px 45px -20px rgba(54,69,79,0.35);
  --shadow-soft: 0 10px 30px -18px rgba(54,69,79,0.28);

  --font-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --font-body: "Work Sans", "Segoe UI", Helvetica, Arial, sans-serif;

  --container: 1180px;
}

body {
  font-family: var(--font-body);
  background: var(--parchment);
  color: var(--ink);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* ---- Typography ---- */
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 600; line-height: 1.12; color: var(--ink); }
h1 { font-size: clamp(2.6rem, 5vw, 4.2rem); font-weight: 500; }
h2 { font-size: clamp(2rem, 3.4vw, 2.8rem); }
h3 { font-size: clamp(1.25rem, 2vw, 1.55rem); }
p { color: var(--ink-soft); }
p + p { margin-top: 1em; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-deep);
}
.eyebrow::before {
  content: "";
  width: 22px;
  height: 1px;
  background: currentColor;
  display: inline-block;
}

/* A lede is a subtitle, not body copy — it follows the heading's width
   rather than being boxed into a narrow measure. */
.lede {
  font-size: 1.15rem;
  color: var(--ink-soft);
}

::selection { background: var(--accent); color: #fff; }

/* ---- Layout helpers ---- */
.wrap {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 28px;
}
.section { padding: clamp(56px, 8vw, 108px) 0; }
.section-alt { background: var(--parchment-deep); }
.section-ink { background: var(--ink); color: #F8F4EA; }
.section-ink p { color: rgba(248,244,234,0.75); }
.section-ink h2, .section-ink h3 { color: #F8F4EA; }

.section-head {
  /* No width cap: a 640px cap was breaking short headings like "Colour you
     can hold in your hand" onto two lines for no reason. They sit on one
     line now, and the three headings genuinely too long to fit still wrap —
     text-wrap: balance just makes those break evenly rather than leaving a
     stray word on the second line. */
  margin-bottom: 48px;
}
.section-head h2, .page-hero h1 { text-wrap: balance; }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.section-head h2 { margin-top: 14px; }

.divider {
  width: 100%;
  height: 1px;
  background: var(--line);
  border: none;
}

/* ---- Buttons ---- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 28px;
  border-radius: 3px;
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  transition: transform 0.25s ease, box-shadow 0.25s ease, background 0.25s ease, color .25s ease;
  white-space: nowrap;
}
.btn-primary {
  background: var(--accent);
  color: #fff;
  box-shadow: var(--shadow-soft);
}
.btn-primary:hover { background: var(--accent-deep); transform: translateY(-2px); }
.btn-ghost {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line);
}
.btn-ghost:hover { border-color: var(--ink); background: rgba(54,69,79,0.04); }
.btn-light {
  background: #F8F4EA;
  color: var(--ink);
}
.btn-light:hover { background: #fff; transform: translateY(-2px); }
.btn-arrow { font-size: 1.1em; transition: transform .25s ease; }
.btn:hover .btn-arrow { transform: translateX(3px); }

.text-link {
  font-weight: 600;
  border-bottom: 1px solid var(--accent);
  padding-bottom: 2px;
  color: var(--accent-deep);
}
.text-link:hover { color: var(--ink); border-color: var(--ink); }

/* ---- Header / Nav ---- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--parchment);
  border-bottom: 1px solid var(--line);
}
.nav-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 28px;
  gap: 24px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  /* Something in a flex row has to give when it is tight. Once .nav-links
     was told not to shrink, the logo became the thing that gave, and it
     came out squashed. Nothing in the header shrinks now: if the row will
     not fit, the gap closes and then the drawer takes over. */
  flex-shrink: 0;
}
.brand img { height: 76px; width: auto; flex-shrink: 0; }
.brand-word {
  font-family: var(--font-display);
  font-size: 1.05rem;
  line-height: 1.15;
}
.brand-word strong { display: block; font-size: 1.2rem; }
.brand-word span { font-size: 0.68rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-soft); }

.nav-links {
  display: flex;
  align-items: center;
  /* Was a flat 34px. With nine items, a phone number and a button, that
     overflowed, and the browser solved it by breaking "In the shop" and the
     phone number across two lines, which pushed the whole header taller and
     looked broken. The gap now gives way before the words do. */
  gap: clamp(14px, 1.7vw, 34px);
  font-size: 0.95rem;
  font-weight: 500;
}
/* No nav item ever breaks mid-label. If there is not room, the gap tightens,
   and then the whole bar becomes the drawer at the breakpoint further down.
   Both are better than a two-line header, and neither depends on guessing
   how wide a webfont will render. */
.nav-links > a,
.nav-dropdown-wrap > a { white-space: nowrap; }
/* And the row itself is never squeezed narrower than its contents. Without
   this the flex layout shrinks each link until the words break, which is
   what produced "In the / shop" stacked in the header. */
.nav-links { flex-shrink: 0; }

.nav-links a { position: relative; padding: 4px 0; }
.nav-links a::after {
  content: "";
  position: absolute; left: 0; right: 100%; bottom: 0;
  height: 2px; background: var(--accent);
  transition: right .25s ease;
}
.nav-links a:hover::after, .nav-links a.active::after { right: 0; }
.nav-links a.active { color: var(--accent-deep); }

/* ---- Brands dropdown ---- */
.nav-dropdown-wrap { position: relative; }
.nav-dropdown-wrap > a { display: inline-flex; align-items: center; gap: 5px; }
.nav-dropdown-wrap .caret { width: 13px; height: 13px; transition: transform .2s ease; }
.nav-dropdown-wrap:hover .caret, .nav-dropdown-wrap:focus-within .caret { transform: rotate(180deg); }

/* .nav-dropdown is the HIT AREA: it starts flush at top:100% (zero gap from
   the trigger) so there is never a dead pixel for the mouse to fall through.
   Visual spacing is done with padding-top instead of a positional gap, and
   the actual card look lives on .nav-dropdown-inner. */
.nav-dropdown {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  min-width: 190px;
  padding-top: 14px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .2s ease;
  z-index: 60;
}
.nav-dropdown-wrap:hover .nav-dropdown,
.nav-dropdown-wrap:focus-within .nav-dropdown {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
.nav-dropdown-inner {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: var(--shadow);
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.nav-dropdown a {
  padding: 10px 12px;
  border-radius: 5px;
  font-size: 0.9rem;
  font-weight: 500;
  white-space: nowrap;
  color: var(--ink);
}
.nav-dropdown a:hover { background: var(--parchment-deep); }
.nav-dropdown a.active { color: var(--accent-deep); font-weight: 600; }


.nav-actions { display: flex; align-items: center; gap: 18px; flex-shrink: 0; }
/* The shop's number is no longer in the header at all: the Visit Us button
   and the footer both carry it, and three copies of one phone number in one
   viewport is two too many. Rules kept, harmless and unused, so an older
   cached page mid-deploy still renders the block sensibly rather than as an
   unstyled stack of text. */
.nav-phone {
  display: flex; flex-direction: column; text-align: right; font-size: 0.85rem;
}
.nav-phone strong { font-size: 0.95rem; white-space: nowrap; }
.nav-phone > span { white-space: nowrap; }
@media (max-width: 1400px) {
  .nav-phone { display: none; }
}

.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  padding: 8px;
}
.nav-toggle span { width: 24px; height: 2px; background: var(--ink); display: block; transition: transform .25s ease, opacity .25s ease; }
.nav-toggle.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---- Hero ---- */
.hero {
  padding: 56px 0 40px;
  overflow: hidden;
}
.hero-grid {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 56px;
  align-items: center;
}
.hero-copy h1 { margin-top: 16px; }
.hero-copy .lede { margin-top: 18px; }
.hero-ctas { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 32px; }

.hero-trust {
  display: flex; align-items: center; gap: 20px;
  margin-top: 44px; padding-top: 28px; border-top: 1px solid var(--line);
  flex-wrap: wrap;
}
.trust-item { display: flex; align-items: center; gap: 10px; font-size: 0.85rem; color: var(--ink-soft); }
.trust-badge {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--ink); color: #F8F4EA;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.trust-badge svg { width: 19px; height: 19px; }

.hero-art { position: relative; }
.hero-art-frame {
  position: relative;
  border-radius: 6px;
  overflow: hidden;
  box-shadow: var(--shadow);
  transform: rotate(1.5deg);
  height: 560px;
}
.hero-art-frame img.hero-slide {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
}

/* Hero crossfade — shared by the background photos AND the floating swatch
   chips, so the chip colours change brand in step with the photo behind
   them. Keyframes are symmetric (opacity 1 at both 0% and 100%) so the
   infinite loop never jumps: without that symmetry, the moment the
   animation restarts causes a visible "flash" back to the first frame. */
.slide-fb, .slide-lg { animation: heroCrossfade 20s ease-in-out infinite; }
.slide-fb { animation-delay: 0s; }
.slide-lg { animation-delay: -10s; }
@keyframes heroCrossfade {
  0%   { opacity: 1; }
  40%  { opacity: 1; }
  50%  { opacity: 0; }
  90%  { opacity: 0; }
  100% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .slide-fb, .slide-lg { animation: none; }
  .slide-fb { opacity: 1; }
  .slide-lg { opacity: 0; }
}

.swatch-chip {
  position: absolute;
  background: var(--card);
  border-radius: 5px;
  box-shadow: var(--shadow-soft);
  padding: 10px;
  width: 128px;
}
.swatch-chip .chip-color { height: 42px; border-radius: 3px; margin-bottom: 8px; }
.swatch-chip .chip-label { font-size: 0.68rem; letter-spacing: 0.04em; color: var(--ink-soft); }
.swatch-chip .chip-name { font-size: 0.78rem; font-weight: 600; }

.chip-1 { top: -26px; left: -20px; transform: rotate(-9deg); }
.chip-1 .chip-color { background: #B4563A; } /* literal "Etruscan Earth" swatch colour, independent of UI accent */
.chip-2 { bottom: -22px; right: -18px; transform: rotate(7deg); }
.chip-2 .chip-color { background: var(--sage); }

/* ---- Intro strip ---- */
.intro-grid {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: 64px;
  align-items: start;
}
.intro-grid .lede { max-width: none; }
.intro-figures {
  display: grid;
  grid-template-columns: repeat(3, auto);
  gap: 8px 40px;
  margin-top: 28px;
}
.figure-item strong { display: block; font-family: var(--font-display); font-size: 2rem; color: var(--accent-deep); }
.figure-item span { font-size: 0.82rem; color: var(--ink-soft); }

/* ---- Brand cards ---- */
.brand-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
}
.brand-card {
  position: relative;
  overflow: hidden;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 36px 32px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  transition: transform .3s ease, box-shadow .3s ease, border-color .4s ease;
  z-index: 0;
}
.brand-card::before,
.brand-card::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .45s ease;
  z-index: -1;
}
.brand-card::before {
  background-image: var(--card-img);
  background-size: cover;
  background-position: center;
}
.brand-card::after {
  background: linear-gradient(190deg, rgba(54,69,79,0.25) 0%, rgba(54,69,79,0.88) 100%);
}
.brand-card:hover { transform: translateY(-6px); box-shadow: var(--shadow); border-color: transparent; }
.brand-card:hover::before, .brand-card:hover::after { opacity: 1; }

.brand-card .brand-logo-box {
  height: 76px; width: 76px;
  display: flex; align-items: center; justify-content: center;
  background: #fff; border-radius: 50%; padding: 10px;
  box-shadow: var(--shadow-soft);
  transition: transform .4s ease;
}
.brand-card:hover .brand-logo-box { transform: scale(1.06); }
.brand-card .brand-logo-box img { height: 100%; width: 100%; object-fit: contain; }
.brand-card .brand-est { font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent); font-weight: 600; transition: color .35s ease; }
.brand-card:hover .brand-est { color: #F8F4EA; }
.brand-card p { font-size: 0.95rem; transition: color .35s ease; }
.brand-card:hover p { color: rgba(248,244,234,0.85); }
.brand-card .text-link { margin-top: auto; align-self: flex-start; transition: color .35s ease, border-color .35s ease; }
.brand-card:hover .text-link { color: #fff; border-color: #fff; }
/* Makes the whole card clickable via the existing link, rather than adding a
   second overlapping anchor — the link's hit area stretches to fill the
   card (which is already position:relative), while staying a single,
   real, accessible link. */
.brand-card .text-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
}
@media (prefers-reduced-motion: reduce) {
  .brand-card, .brand-card::before, .brand-card::after, .brand-card .brand-logo-box { transition: none; }
}

/* ---- Gallery ---- */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 190px;
  gap: 18px;
}
.gallery-grid figure { position: relative; overflow: hidden; border-radius: 6px; }
.gallery-grid img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; }
.gallery-grid figure:hover img { transform: scale(1.06); }
.gallery-grid figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 14px 16px;
  background: linear-gradient(0deg, rgba(54,69,79,0.75), rgba(54,69,79,0));
  color: #fff; font-size: 0.8rem; font-weight: 500;
  opacity: 0; transform: translateY(6px);
  transition: opacity .3s ease, transform .3s ease;
}
.gallery-grid figure:hover figcaption { opacity: 1; transform: translateY(0); }
.g-tall { grid-row: span 2; }
.g-wide { grid-column: span 2; }
.g-feature { grid-column: span 2; grid-row: span 2; }

/* ---- Testimonials ---- */
.testi-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
}
.testi-card {
  background: var(--card);
  border-radius: 8px;
  padding: 32px;
  border-left: 3px solid var(--accent);
}
.testi-mark { font-family: var(--font-display); font-size: 2.6rem; color: var(--accent); line-height: 1; display: block; margin-bottom: 6px; }
.testi-quote { font-family: var(--font-display); font-size: 1.12rem; color: var(--ink); }
.testi-name { margin-top: 18px; font-size: 0.88rem; font-weight: 600; }
.testi-role { font-size: 0.8rem; color: var(--ink-soft); }

/* ---- Visit / CTA band ---- */
.visit-band {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 48px;
  align-items: center;
}
.visit-details { display: grid; gap: 18px; margin-top: 26px; }
.visit-row { display: flex; gap: 14px; }
.visit-row .ic {
  width: 38px; height: 38px; border-radius: 50%;
  background: rgba(248,244,234,0.1);
  border: 1px solid rgba(248,244,234,0.25);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; color: #F8F4EA;
}
.visit-row .ic svg { width: 18px; height: 18px; }
.visit-row strong { display: block; font-size: 0.95rem; }
.visit-row span, .visit-row a { font-size: 0.9rem; color: rgba(248,244,234,0.75); }
.visit-map {
  border-radius: 8px; overflow: hidden; box-shadow: var(--shadow);
  border: 6px solid #fff;
}
.visit-map iframe { width: 100%; height: 320px; border: 0; display: block; }

/* ---- Footer ---- */
.site-footer { background: var(--ink); color: rgba(248,244,234,0.7); padding: 64px 0 26px; }
.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 0.8fr 0.8fr 1fr;
  gap: 40px;
  padding-bottom: 44px;
}
.footer-brand img { height: 58px; margin-bottom: 16px; }
.footer-brand p { max-width: 34ch; font-size: 0.9rem; color: rgba(248,244,234,0.6); }
.footer-col h4 { color: #F8F4EA; font-size: 0.82rem; letter-spacing: 0.1em; text-transform: uppercase; margin-bottom: 18px; font-family: var(--font-body); font-weight: 600; }
.footer-col ul { display: grid; gap: 12px; font-size: 0.92rem; }
.footer-col a:hover { color: #fff; }
.footer-brands { display: flex; gap: 12px; align-items: center; margin-top: 6px; flex-wrap: wrap; }
.brand-chip {
  display: flex; align-items: center;
  background: #fff; border-radius: 50%;
  padding: 7px;
}
.footer-brands img { height: 38px; width: 38px; object-fit: contain; }
.social-row { display: flex; gap: 12px; margin-top: 6px; }
.social-row a {
  width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid rgba(248,244,234,0.25);
  display: flex; align-items: center; justify-content: center;
  transition: background .25s ease, border-color .25s ease;
}
.social-row a svg { width: 16px; height: 16px; }
.social-row a:hover { background: var(--accent); border-color: var(--accent); }
.footer-bottom {
  display: flex; justify-content: space-between; align-items: center;
  padding-top: 24px; border-top: 1px solid rgba(248,244,234,0.12);
  font-size: 0.82rem; flex-wrap: wrap; gap: 12px 24px;
}
/* Kept on one line where there is room for one. The separators are the
   only thing allowed to break, so the company number never ends up on a
   line of its own looking like a heading. */
.footer-identity { min-width: 0; }
.footer-bottom a:hover { color: #fff; }
.footer-legal-links { display: flex; gap: 20px; flex-wrap: wrap; }

/* ---- Legal / prose pages (Privacy, Cookies) ---- */
.legal-prose { max-width: 760px; }
.legal-prose h2 { font-size: 1.5rem; margin-top: 48px; margin-bottom: 14px; }
.legal-prose h2:first-child { margin-top: 0; }
.legal-prose h3 { font-size: 1.1rem; margin-top: 26px; margin-bottom: 10px; font-family: var(--font-body); font-weight: 700; }
.legal-prose p { margin-bottom: 14px; }
.legal-prose ul { margin: 0 0 14px; padding-left: 22px; list-style: disc; }
.legal-prose li { margin-bottom: 8px; color: var(--ink-soft); }
.legal-prose li strong { color: var(--ink); }
.legal-prose a { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 2px; }
.legal-prose .legal-meta { color: var(--ink-soft); font-size: 0.88rem; margin-bottom: 36px; }
.legal-prose .legal-note {
  background: var(--card); border-left: 3px solid var(--accent);
  border-radius: 4px; padding: 16px 20px; margin: 18px 0; font-size: 0.92rem;
}

/* ---- Page hero (About / Contact) ---- */
.page-hero {
  padding: 64px 0 48px;
  border-bottom: 1px solid var(--line);
}
.page-hero .eyebrow { margin-bottom: 14px; }
/* Headings run to the container width and break only when they must. */
.page-hero h1 { max-width: none; }
.page-hero .lede { margin-top: 16px; }

/* ---- Page hero, side-by-side photo variant ---- */
.page-hero-split {
  padding: 64px 0;
  border-bottom: 1px solid var(--line);
}
.page-hero-split-row {
  display: flex;
  align-items: center;
  gap: 48px;
}
.page-hero-split-row .page-hero-text { flex: 1; min-width: 0; }
.page-hero-split-row .page-hero-text h1 { max-width: none; }
.page-hero-split-row .page-hero-text .lede { margin-top: 16px; }
.page-hero-split-row .page-hero-photo {
  width: 420px;
  height: 460px;
  flex-shrink: 0;
  border-radius: 14px;
  overflow: hidden;
}
.page-hero-split-row .page-hero-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
@media (max-width: 980px) {
  .page-hero-split-row { flex-direction: column-reverse; gap: 32px; }
  .page-hero-split-row .page-hero-photo { width: 100%; height: 320px; }
}
@media (max-width: 640px) {
  .page-hero-split-row .page-hero-photo { height: 240px; }
}

/* ---- About page ---- */
.about-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: center;
}
.about-photo { position: relative; }
.about-photo img { border-radius: 8px; box-shadow: var(--shadow); width: 100%; height: 460px; object-fit: cover; }
.about-photo-caption {
  position: absolute; bottom: -22px; left: 24px; right: 24px;
  background: var(--card); border-radius: 6px; padding: 14px 18px;
  box-shadow: var(--shadow-soft); font-size: 0.85rem; font-weight: 500;
}

.values-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
.value-card { padding: 30px 24px; background: var(--card); border-radius: 8px; border: 1px solid var(--line); }
.value-card .value-num { font-family: var(--font-display); color: var(--accent); font-size: 1.3rem; display: block; margin-bottom: 14px; }
.value-card h3 { font-size: 1.05rem; margin-bottom: 10px; }
.value-card p { font-size: 0.9rem; }

.pull-quote {
  max-width: 780px; margin: 0 auto; text-align: center;
}
.pull-quote p { font-family: var(--font-display); font-size: clamp(1.35rem, 2.4vw, 1.8rem); color: var(--ink); font-weight: 500; line-height: 1.4; }
.pull-quote .testi-mark { display: block; margin: 0 auto 6px; }
.pull-quote cite { display: block; margin-top: 22px; font-style: normal; font-size: 0.85rem; color: var(--ink-soft); font-weight: 600; }

/* ---- Contact page ---- */
.contact-grid {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: 56px;
  align-items: start;
}
.contact-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 36px;
}
.contact-card h3 { margin-bottom: 22px; }
.contact-list { display: grid; gap: 22px; }
.contact-list .ic { color: var(--accent); width: 22px; height: 22px; flex-shrink: 0; margin-top: 2px; }
.contact-list .ic svg { width: 100%; height: 100%; }
.contact-list li { display: flex; gap: 14px; align-items: flex-start; }
.contact-list strong { display: block; font-size: 0.92rem; }
.contact-list span, .contact-list a { font-size: 0.9rem; color: var(--ink-soft); }
.contact-list a:hover { color: var(--accent-deep); }
.hours-table { margin-top: 22px; padding-top: 22px; border-top: 1px solid var(--line); font-size: 0.9rem; }
.hours-table div { display: flex; justify-content: space-between; padding: 6px 0; }
.hours-table div span:first-child { color: var(--ink-soft); }
.hours-table div span:last-child { font-weight: 600; }

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.form-grid .full { grid-column: 1 / -1; }
.field label { display: block; font-size: 0.82rem; font-weight: 600; margin-bottom: 8px; letter-spacing: 0.02em; }
.field input, .field textarea {
  width: 100%;
  border: 1px solid var(--line);
  background: var(--card);
  border-radius: 4px;
  padding: 13px 14px;
  font-size: 0.95rem;
  color: var(--ink);
  transition: border-color .2s ease, box-shadow .2s ease;
}
.field input:focus, .field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(54,69,79,0.18);
}
.field textarea { resize: vertical; min-height: 130px; }
.form-note { font-size: 0.82rem; color: var(--ink-soft); margin-top: 6px; }
/* Shown in place of the spam check when it fails to load, so it has to read
   as a real notice rather than small print — it is carrying the phone
   number that is now the only way to reach the shop from this page. */
.form-note-warn {
  font-size: 0.95rem; line-height: 1.55; color: var(--ink);
  margin-top: 0; padding: 14px 16px; border-radius: 10px;
  background: var(--parchment-deep); border: 1px solid var(--line);
}
.cf-turnstile { margin: 6px 0 4px; }
.form-success {
  display: none;
  margin-top: 18px;
  padding: 14px 18px;
  background: rgba(124,138,94,0.15);
  border: 1px solid var(--sage);
  border-radius: 6px;
  font-size: 0.9rem;
  color: var(--ink);
}
.form-success.show { display: block; }
.form-success.error {
  background: var(--accent-tint);
  border-color: var(--accent);
}
.field.has-error input, .field.has-error textarea { border-color: var(--accent); }

.map-full { border-radius: 8px; overflow: hidden; box-shadow: var(--shadow-soft); margin-top: 20px; }
.map-full iframe { width: 100%; height: 380px; border: 0; display: block; }

/* focus visibility */
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* Pill-shaped controls get a rounded ring instead of the default square
   outline, which otherwise sits awkwardly outside a fully-rounded button. */
.category-toggle-btn:focus-visible,
.brand-tab:focus-visible,
.nav-dropdown-wrap > a:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--parchment-deep), 0 0 0 4px var(--accent);
}

/* ---- Brand product pages ---- */
.brand-tabs {
  display: flex; gap: 10px; flex-wrap: wrap;
  margin-top: 28px;
}
.brand-tab {
  padding: 10px 20px;
  border-radius: 30px;
  border: 1px solid var(--line);
  font-size: 0.88rem;
  font-weight: 600;
  background: var(--card);
  transition: background .2s ease, border-color .2s ease, color .2s ease;
}
.brand-tab:hover { border-color: var(--accent); }
.brand-tab.active { background: var(--ink); color: #F8F4EA; border-color: var(--ink); }

/* ---- Paint / Wallpaper category toggle ---- */
.category-toggle {
  display: inline-flex;
  gap: 4px;
  background: var(--parchment-deep);
  border-radius: 30px;
  padding: 4px;
  margin: 36px 0 -8px;
}
.category-toggle-btn {
  padding: 11px 28px;
  border-radius: 26px;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--ink-soft);
  transition: background .2s ease, color .2s ease;
}
.category-toggle-btn:hover { color: var(--ink); }
.category-toggle-btn.active { background: var(--ink); color: #F8F4EA; }
.category-panel[hidden] { display: none; }

.brand-hero {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 32px;
  align-items: stretch;
}
.brand-hero-logo {
  aspect-ratio: 1; height: auto; width: auto;
  max-width: 220px; max-height: 220px;
  border-radius: 50%;
  background: var(--card);
  border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  padding: 26px;
  flex-shrink: 0;
}
.brand-hero-logo img { height: 100%; width: auto; max-width: 100%; object-fit: contain; }

.page-hero-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
}
.page-hero-main { flex: 1; min-width: 0; }

/* ---- Paint chip crossfade, an alternative to the tin photo ---- */
.chip-crossfade {
  flex-shrink: 0;
  position: relative;
  width: 220px;
  height: 220px;
}
.paint-chip {
  position: absolute; inset: 0;
  background: var(--card);
  border-radius: 12px;
  box-shadow: var(--shadow);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.paint-chip .chip-swatch { flex: 1; }
.paint-chip .chip-info { padding: 16px 18px 18px; }
.paint-chip .chip-num {
  display: block; font-size: 0.72rem; letter-spacing: 0.04em;
  color: var(--ink-soft); margin-bottom: 2px;
}
.paint-chip .chip-name {
  font-family: var(--font-display); font-size: 1.05rem; color: var(--ink); line-height: 1.2;
}
.chip-crossfade .paint-chip { animation: chipCrossfade 16s ease-in-out infinite; }
@keyframes chipCrossfade {
  0%   { opacity: 1; }
  20%  { opacity: 1; }
  25%  { opacity: 0; }
  95%  { opacity: 0; }
  100% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .chip-crossfade .paint-chip { animation: none; opacity: 0; }
  .chip-crossfade .paint-chip:first-child { opacity: 1; }
}
@media (max-width: 1020px) {
  .chip-crossfade { width: 140px; height: 140px; }
  .paint-chip .chip-info { padding: 10px 12px 12px; }
  .paint-chip .chip-num { font-size: 0.62rem; }
  .paint-chip .chip-name { font-size: 0.82rem; }
}
@media (max-width: 640px) {
  .chip-crossfade { display: none; }
}
.swatch-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 16px;
}
.swatch-card {
  border-radius: 6px;
  overflow: hidden;
  box-shadow: var(--shadow-soft);
  background: var(--card);
  transition: transform .25s ease, box-shadow .25s ease;
}
.swatch-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.swatch-block { height: 76px; }
.swatch-label { padding: 8px 10px; }
.swatch-label .s-name { display: block; font-size: 0.78rem; font-weight: 600; line-height: 1.25; }
.swatch-label .s-num { display: block; font-size: 0.68rem; color: var(--ink-soft); margin-top: 2px; }

.range-note {
  margin-top: 32px;
  padding: 20px 24px;
  background: var(--card);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  font-size: 0.92rem;
}

/* Collection cards in the wallpaper grid open a modal on click, showing
   every colourway in that collection. */
.wallpaper-card[data-collection] { cursor: pointer; }
.wallpaper-card[data-collection]:hover .wallpaper-swatch img { transform: scale(1.05); }
.wallpaper-card[data-collection] .wallpaper-label small { color: var(--accent); font-weight: 600; }

.wp-modal-overlay {
  position: fixed; inset: 0;
  background: rgba(54,69,79,0.5);
  opacity: 0; visibility: hidden;
  transition: opacity .2s ease, visibility .2s ease;
  z-index: 400;
}
.wp-modal-overlay.open { opacity: 1; visibility: visible; }
.wp-modal {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -46%);
  width: 640px; max-width: calc(100vw - 32px);
  max-height: calc(100vh - 80px);
  background: var(--parchment);
  border-radius: 12px;
  box-shadow: 0 24px 60px -12px rgba(54,69,79,0.4);
  z-index: 410;
  opacity: 0; visibility: hidden;
  transition: opacity .2s ease, transform .2s ease, visibility .2s ease;
  display: flex; flex-direction: column;
}
.wp-modal.open { opacity: 1; visibility: visible; transform: translate(-50%, -50%); }
.wp-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 22px; border-bottom: 1px solid var(--line); flex-shrink: 0;
}
.wp-modal-title { font-size: 1.2rem; }
.wp-modal-close { width: 34px; height: 34px; display: flex; align-items: center; justify-content: center; border-radius: 50%; flex-shrink: 0; }
.wp-modal-close:hover { background: var(--parchment-deep); }
.wp-modal-close svg { width: 18px; height: 18px; }
.wp-modal-body {
  overflow-y: auto; padding: 20px 22px;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;
}
.wp-modal-item { position: relative; }
.wp-modal-item-swatch {
  height: 110px; border-radius: 6px; background-size: cover; background-position: center;
  box-shadow: var(--shadow-soft);
}
.wp-modal-item-info { padding: 8px 2px 0; }
.wp-modal-item-info strong { display: block; font-size: 0.84rem; }
.wp-modal-item-info span { display: block; font-size: 0.76rem; color: var(--ink-soft); }
.wp-modal-item .sb-add-btn { top: 8px; right: 8px; }
@media (max-width: 640px) {
  .wp-modal-body { grid-template-columns: repeat(2, 1fr); }
}

.finish-list { display: flex; flex-wrap: wrap; gap: 12px; }
.finish-chip {
  padding: 10px 18px;
  border-radius: 30px;
  background: var(--card);
  border: 1px solid var(--line);
  font-size: 0.86rem;
  font-weight: 600;
}

.wallpaper-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 20px;
}
.wallpaper-card {
  border-radius: 8px;
  overflow: hidden;
  background: var(--card);
  box-shadow: var(--shadow-soft);
  transition: transform .25s ease, box-shadow .25s ease;
}
.wallpaper-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.wallpaper-swatch { height: 150px; }
.wallpaper-swatch img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .35s ease; }
.wallpaper-swatch.pattern-fill { background-size: 22px 22px; }
.wallpaper-label { padding: 12px 14px; }
.wallpaper-label span { font-family: var(--font-display); font-size: 1rem; display: block; }
.wallpaper-label small { font-size: 0.76rem; color: var(--ink-soft); }

@media (max-width: 1020px) {
  .swatch-grid { grid-template-columns: repeat(5, 1fr); }
  .wallpaper-grid { grid-template-columns: repeat(3, 1fr); }
  .brand-hero { grid-template-columns: 1fr; text-align: left; }
  .page-hero-row { flex-direction: column; align-items: flex-start; gap: 24px; }
}
@media (max-width: 640px) {
  .swatch-grid { grid-template-columns: repeat(3, 1fr); gap: 10px; }
  .wallpaper-grid { grid-template-columns: repeat(2, 1fr); }
  .brand-hero-logo { width: 100px; height: 100px; aspect-ratio: unset; }
}

/* ---- Gentle load-in ----
   Animation-only (no static opacity:0 base rule) so content is never
   left hidden if animations don't run for any reason. */
@keyframes revealIn {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: translateY(0); }
}
.reveal { animation: revealIn 0.6s ease-out both; }
@media (prefers-reduced-motion: reduce) {
  .reveal { animation: none; }
}

/* =========================================================
   Responsive
   ========================================================= */
@media (max-width: 1020px) {
  .hero-grid, .about-grid, .intro-grid, .visit-band, .contact-grid { grid-template-columns: 1fr; }
  .hero-art { order: -1; }
  .hero-art-frame { height: 380px; }
  .brand-grid { grid-template-columns: repeat(3, 1fr); gap: 18px; }
  .gallery-grid { grid-template-columns: repeat(2, 1fr); }
  .testi-grid { grid-template-columns: 1fr; }
  .values-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .about-photo { margin-bottom: 40px; }
}

/* Raised from 860px. Nine items, a phone number and a button do not fit a
   laptop bar, and the drawer is a better answer than a cramped row. */
@media (max-width: 1180px) {
  /* The closed drawer is slid off the right of the screen. transform alone
     only moves it: it stays in the tab order and in the accessibility tree,
     so a keyboard user tabbing the header falls into fourteen links they
     cannot see, and a screen reader reads a menu that is not open.
     `visibility: hidden` takes it out of both. The delay keeps the slide
     visible on the way out — visibility flips only once the transform has
     finished — while opening flips it immediately so the panel is reachable
     for the whole of its slide in. */
  .nav-links { position: fixed; top: 82px; left: 0; right: 0; bottom: 0;
    background: var(--parchment); flex-direction: column; align-items: flex-start;
    padding: 28px; gap: 8px; transform: translateX(100%);
    visibility: hidden;
    transition: transform .3s ease, visibility 0s linear .3s;
    overflow-y: auto; z-index: 90;
  }
  .nav-links.open {
    transform: translateX(0);
    visibility: visible;
    transition: transform .3s ease, visibility 0s linear 0s;
  }
  @media (prefers-reduced-motion: reduce) {
    .nav-links { transition: none; }
    .nav-links.open { transition: none; }
  }
  .nav-links a { width: 100%; padding: 14px 0; border-bottom: 1px solid var(--line); font-size: 1.05rem; }
  .nav-phone { display: none; }
  .nav-toggle { display: flex; }
  .brand-grid { grid-template-columns: 1fr; }
  .form-grid { grid-template-columns: 1fr; }

  /* Brands dropdown becomes a plain indented sub-list in the mobile panel */
  .nav-dropdown-wrap { width: 100%; }
  .nav-dropdown-wrap > a { width: 100%; justify-content: space-between; padding: 14px 0; border-bottom: 1px solid var(--line); }
  .nav-dropdown-wrap .caret { display: none; }
  .nav-dropdown {
    position: static;
    opacity: 1; visibility: visible; pointer-events: auto;
    width: 100%; min-width: 0; padding-top: 0;
    left: auto; transform: none;
  }
  .nav-dropdown-inner {
    background: transparent; border: none; box-shadow: none;
    padding: 0 0 6px; gap: 0;
  }
  .nav-dropdown a { width: 100%; padding: 12px 0 12px 16px; font-size: 0.98rem; color: var(--ink-soft); border-bottom: 1px solid var(--line); border-radius: 0; }
}

@media (max-width: 640px) {
  .intro-figures { grid-template-columns: repeat(2, auto); }
  .gallery-grid { grid-template-columns: 1fr 1fr; grid-auto-rows: 150px; }
  .g-wide { grid-column: span 2; }
  .values-grid { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr; gap: 32px; }
  .footer-bottom { flex-direction: column; align-items: flex-start; }
  .swatch-chip { width: 104px; padding: 8px; }
  .chip-1 { left: -10px; top: -18px; }
  .chip-2 { right: -10px; bottom: -18px; }
  .hero-trust { gap: 14px; }
  .visit-map iframe, .map-full iframe { height: 260px; }
}

/* =========================================================
   Swatch Book
   ========================================================= */

/* "+" add-button injected onto every paint/wallpaper card */
.swatch-card, .wallpaper-card { position: relative; }
.sb-add-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(255,255,255,0.92);
  border: 1px solid rgba(54,69,79,0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  box-shadow: 0 2px 8px rgba(54,69,79,0.18);
  transition: background .2s ease, transform .2s ease, color .2s ease, border-color .2s ease;
  z-index: 5;
}
.sb-add-btn svg { width: 15px; height: 15px; transition: transform .2s ease; }
.sb-add-btn:hover { transform: scale(1.08); border-color: var(--accent); }
.sb-add-btn.added { background: var(--accent); color: #fff; border-color: var(--accent); }
.sb-add-btn.added svg { transform: rotate(45deg); }

/* Maker's mark on a mixed-brand grid
   ------------------------------------------------------------------
   Bottom-left, opposite the "add to swatch book" button, so the two never
   collide. Each mark keeps its own proportions — fixed height, automatic
   width — because the roundel and the two wordmarks are nothing like the
   same shape. Hidden the moment a brand filter is applied: the heading and
   the active chip already say whose colours these are. */
.swatch-block, .wallpaper-swatch { position: relative; }
.card-brand-badge {
  position: absolute;
  left: 8px;
  bottom: 8px;
  display: flex;
  align-items: center;
  height: 28px;
  padding: 0 8px;
  border-radius: 12px;
  background: rgba(255,255,255,0.94);
  box-shadow: 0 1px 5px rgba(54,69,79,0.16);
  pointer-events: none;
  z-index: 4;
}
/* Two constraints, not one: the tall two-line wordmark is capped by height,
   the long single-line one by width, and each keeps its own proportions. */
.card-brand-badge img {
  max-height: 20px;
  max-width: 72px;
  width: auto;
  height: auto;
  display: block;
}
/* A roundel is its own badge already — no pill, just the mark, big enough
   to recognise. Rings of white keep it off a dark or busy paper. */
.card-brand-badge-round {
  height: auto;
  padding: 0;
  border-radius: 50%;
  background: none;
  box-shadow: 0 1px 5px rgba(54,69,79,0.22);
}
.card-brand-badge-round img {
  height: 30px;
  border-radius: 50%;
  border: 1.5px solid rgba(255,255,255,0.9);
}
/* The paint block is only 76px tall, so its marks sit a size down. */
.swatch-block .card-brand-badge { height: 26px; padding: 0 7px; left: 7px; bottom: 7px; }
.swatch-block .card-brand-badge img { max-height: 17px; max-width: 66px; }
.swatch-block .card-brand-badge-round { height: auto; padding: 0; }
.swatch-block .card-brand-badge-round img { height: 25px; }

.is-brand-filtered .card-brand-badge { display: none; }

@media (max-width: 600px) {
  .card-brand-badge { height: 21px; padding: 0 6px; left: 6px; bottom: 6px; }
  .card-brand-badge img { max-height: 16px; max-width: 60px; }
  .card-brand-badge-round img { height: 25px; }
  .swatch-block .card-brand-badge { height: 20px; }
  .swatch-block .card-brand-badge img { max-height: 15px; max-width: 56px; }
  .swatch-block .card-brand-badge-round img { height: 22px; }
}

/* Floating launcher */
.sb-launcher {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 200;
  display: flex;
  align-items: center;
  gap: 9px;
  background: var(--ink);
  color: #F8F4EA;
  border-radius: 30px;
  padding: 13px 20px 13px 16px;
  box-shadow: 0 12px 30px -8px rgba(54,69,79,0.55);
  font-size: 0.88rem;
  font-weight: 600;
  transition: transform .2s ease;
}
.sb-launcher:hover { transform: translateY(-2px); }

/* The swatch-book launcher and the cookie notice both live in the bottom
   corner, so while the notice is up the launcher steps above it. The height
   is measured in JS and written to --cookie-notice-h, because the notice
   wraps to two or three lines depending on the width. */
body.has-cookie-notice .sb-launcher {
  bottom: calc(var(--cookie-notice-h, 120px) + 34px);
  transition: bottom .3s ease, transform .2s ease;
}
.sb-launcher svg { width: 18px; height: 18px; }
.sb-launcher .sb-count {
  background: var(--accent);
  color: #fff;
  min-width: 20px;
  height: 20px;
  border-radius: 10px;
  font-size: 0.72rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 5px;
}
.sb-launcher .sb-count:empty,
.sb-launcher .sb-count[data-count="0"] { display: none; }

/* Overlay + panel */
.sb-overlay {
  position: fixed; inset: 0;
  background: rgba(54,69,79,0.45);
  opacity: 0; visibility: hidden;
  transition: opacity .25s ease, visibility .25s ease;
  z-index: 210;
}
.sb-overlay.open { opacity: 1; visibility: visible; }

.sb-panel {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: 420px;
  max-width: 92vw;
  background: var(--parchment);
  box-shadow: -20px 0 45px -20px rgba(54,69,79,0.5);
  z-index: 220;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform .3s ease;
}
.sb-panel.open { transform: translateX(0); }

.sb-panel-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  padding: 20px 22px;
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
  gap: 12px;
}
.sb-panel-head h3 { font-size: 1.15rem; }
.sb-panel-head-text { min-width: 0; flex: 1; }
.sb-name-field { margin-top: 8px; }
.sb-name-input {
  border: none; border-bottom: 1px dashed var(--line);
  background: transparent; font-family: var(--font-display); font-size: 0.98rem;
  padding: 3px 0 5px; width: 100%; color: var(--ink);
}
.sb-name-input::placeholder { color: var(--ink-soft); opacity: 0.75; font-family: var(--font-body); font-size: 0.85rem; }
.sb-name-input:focus { outline: none; border-color: var(--accent); }
.sb-panel-close { width: 34px; height: 34px; display: flex; align-items: center; justify-content: center; border-radius: 50%; flex-shrink: 0; }
.sb-panel-close:hover { background: var(--parchment-deep); }
.sb-panel-close svg { width: 18px; height: 18px; }

.sb-panel-body { flex: 1; overflow-y: auto; padding: 16px 22px; }
.sb-empty { padding: 40px 6px; text-align: center; color: var(--ink-soft); font-size: 0.92rem; }
.sb-empty svg { width: 36px; height: 36px; margin: 0 auto 14px; opacity: 0.4; display: block; }
.sb-empty strong { color: var(--ink); font-weight: 600; }
.sb-empty-more { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.sb-empty-more a { font-weight: 600; color: var(--accent-deep); border-bottom: 1px solid var(--line); }
.sb-empty-more a:hover { border-bottom-color: var(--accent); }

/* The help link under the panel's own buttons. Deliberately the quietest
   thing in the footer: it is there for the one visitor in twenty who does
   not know what this is, and must not compete with Print or Send. */
.sb-help-row { text-align: center; margin-bottom: 16px; font-size: 0.8rem; }
.sb-help-row a { color: var(--ink-soft); border-bottom: 1px solid var(--line); }
.sb-help-row a:hover { color: var(--accent-deep); border-bottom-color: var(--accent); }

/* Add-a-room field */
.sb-add-room { display: flex; gap: 8px; margin-bottom: 20px; }
.sb-add-room input {
  flex: 1; border: 1px solid var(--line); background: var(--card);
  border-radius: 4px; padding: 10px 12px; font-size: 0.88rem; color: var(--ink);
}
.sb-add-room input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(54,69,79,0.18); }
.sb-add-room .btn { padding: 10px 18px; font-size: 0.85rem; flex-shrink: 0; }

/* Rooms */
.sb-room { margin-bottom: 18px; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: var(--card); }
.sb-room-head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px;
  background: var(--parchment-deep);
  border-bottom: 1px solid var(--line);
}
.sb-room-icon { display: flex; color: var(--ink-soft); flex-shrink: 0; }
.sb-room-icon svg { width: 16px; height: 16px; }
.sb-room-name-input {
  flex: 1; min-width: 0; background: transparent; border: none;
  font-family: var(--font-display); font-size: 0.98rem; font-weight: 600; color: var(--ink);
  padding: 4px 2px; border-radius: 3px;
}
.sb-room-name-input:hover, .sb-room-name-input:focus { background: rgba(255,255,255,0.6); outline: none; }
.sb-room-title { flex: 1; font-family: var(--font-display); font-size: 0.98rem; font-weight: 600; }
.sb-room-count {
  font-size: 0.72rem; font-weight: 600; color: var(--ink-soft);
  background: rgba(54,69,79,0.08); border-radius: 10px; padding: 2px 8px; flex-shrink: 0;
}
.sb-room-delete { width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: var(--ink-soft); flex-shrink: 0; }
.sb-room-delete:hover { background: rgba(180,86,58,0.12); color: var(--accent-deep); }
.sb-room-delete svg { width: 14px; height: 14px; }

.sb-room-dropzone { padding: 6px 12px; min-height: 20px; transition: background .15s ease; }
.sb-room-dropzone.drag-over { background: var(--accent-tint); }
.sb-room-empty { padding: 14px 4px; font-size: 0.8rem; color: var(--ink-soft); font-style: italic; }
.sb-room-unsorted { border-style: dashed; background: transparent; }
.sb-room-unsorted .sb-room-head { background: transparent; }

.sb-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
}
.sb-room-dropzone .sb-item:last-child { border-bottom: none; }
.sb-drag-handle { display: flex; color: var(--ink-soft); flex-shrink: 0; cursor: grab; touch-action: none; padding: 4px; margin: -4px; }
.sb-drag-handle svg { width: 15px; height: 15px; }
.sb-drag-handle:hover { color: var(--ink); }
.sb-item-swatch { width: 40px; height: 40px; border-radius: 6px; flex-shrink: 0; background-size: cover; background-position: center; box-shadow: var(--shadow-soft); }
.sb-item-info { flex: 1; min-width: 0; }
.sb-item-info strong { display: block; font-size: 0.86rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sb-item-info span { display: block; font-size: 0.76rem; color: var(--ink-soft); }
.sb-item-room-select {
  font-size: 0.74rem; max-width: 84px; border: 1px solid var(--line); border-radius: 4px;
  background: var(--parchment); color: var(--ink-soft); padding: 4px 4px; flex-shrink: 0;
}
.sb-item-remove { width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: var(--ink-soft); flex-shrink: 0; }
.sb-item-remove:hover { background: var(--parchment-deep); color: var(--ink); }
.sb-item-remove svg { width: 13px; height: 13px; }

.sb-dragging-source { opacity: 0.35; }
.sb-drag-ghost {
  position: fixed;
  top: 0; left: 0;
  z-index: 300;
  pointer-events: none;
  background: var(--card);
  border-radius: 6px;
  box-shadow: var(--shadow);
  border: 1px solid var(--accent);
  opacity: 0.96;
}

.sb-panel-foot { flex-shrink: 0; padding: 18px 22px 22px; border-top: 1px solid var(--line); background: var(--card); }
/* Three buttons in a 380px panel do not fit side by side — "Request
   samples" is the longest label and was being clipped. Wrapping lets the
   third drop to its own line rather than overflowing, and min-width:0 stops
   a long label forcing the row wider than the panel. */
.sb-actions-row {
  display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 14px;
}
.sb-actions-row .btn {
  flex: 1 1 130px;
  min-width: 0;
  justify-content: center;
  padding-left: 12px; padding-right: 12px;
  white-space: nowrap;
}
.sb-clear-link, .sb-reset-link { font-size: 0.8rem; color: var(--ink-soft); }
.sb-clear-link:hover, .sb-reset-link:hover { color: var(--accent-deep); }
.sb-clear-reset-row { display: flex; justify-content: center; align-items: center; gap: 10px; margin-bottom: 16px; color: var(--line); font-size: 0.8rem; }
.sb-clear-link:hover { color: var(--accent-deep); }

.sb-email-form { border-top: 1px solid var(--line); padding-top: 16px; }
.sb-email-form label { display: block; font-size: 0.8rem; font-weight: 600; margin-bottom: 8px; }
.sb-email-row { display: flex; gap: 8px; }
.sb-email-row input {
  flex: 1; border: 1px solid var(--line); background: var(--parchment);
  border-radius: 4px; padding: 11px 12px; font-size: 0.9rem; color: var(--ink);
}
.sb-email-row input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(54,69,79,0.18); }
.sb-email-status { font-size: 0.82rem; margin-top: 10px; }
.sb-email-status.success { color: var(--sage); }
.sb-email-status.error { color: var(--accent-deep); }
.sb-turnstile-wrap { margin-top: 10px; }

@media (max-width: 640px) {
  .sb-launcher span.sb-label { display: none; }
  .sb-launcher { padding: 14px; }
  .sb-panel { width: 100%; max-width: 100%; }
}

/* ---- Confirm modal (on-brand replacement for window.confirm) ---- */
.sb-confirm-overlay {
  position: fixed; inset: 0;
  background: rgba(54,69,79,0.5);
  opacity: 0; visibility: hidden;
  transition: opacity .2s ease, visibility .2s ease;
  z-index: 400;
}
.sb-confirm-overlay.open { opacity: 1; visibility: visible; }
.sb-confirm-modal {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -46%);
  width: 360px; max-width: calc(100vw - 40px);
  background: var(--parchment);
  border-radius: 10px;
  box-shadow: 0 24px 60px -12px rgba(54,69,79,0.4);
  padding: 26px 26px 22px;
  z-index: 410;
  opacity: 0; visibility: hidden;
  transition: opacity .2s ease, transform .2s ease, visibility .2s ease;
}
.sb-confirm-modal.open { opacity: 1; visibility: visible; transform: translate(-50%, -50%); }
.sb-confirm-title { font-size: 1.1rem; margin-bottom: 8px; }
.sb-confirm-message { font-size: 0.9rem; color: var(--ink-soft); line-height: 1.5; margin-bottom: 22px; }
.sb-confirm-actions { display: flex; gap: 10px; justify-content: flex-end; }
.sb-confirm-actions .btn { padding: 10px 20px; font-size: 0.86rem; }

/* ---- Print sheet: hidden on screen, only element shown when printing ---- */
.sb-print-sheet { display: none; }
@media print {
  body > *:not(.sb-print-sheet) { display: none !important; }
  .sb-print-sheet { display: block !important; padding: 24px; }
  /* Chrome/Safari hide background-colors and background-images when printing
     unless explicitly told not to — without this, every swatch prints as an
     empty box (borders still show since those aren't a "background"). */
  .sb-print-sheet, .sb-print-sheet * {
    -webkit-print-color-adjust: exact !important;
    print-color-adjust: exact !important;
    color-adjust: exact !important;
  }
  .sb-print-sheet h1 { font-family: var(--font-display); font-size: 1.8rem; margin-bottom: 4px; }
  .sb-print-letterhead {
    display: flex; align-items: center; gap: 14px;
    padding-bottom: 16px; margin-bottom: 22px;
    border-bottom: 2px solid #36454F;
  }
  .sb-print-logo { width: 52px; height: 52px; object-fit: contain; }
  .sb-print-shop-info { font-size: 0.78rem; line-height: 1.5; color: #444; }
  .sb-print-shop-info strong { font-family: var(--font-display); font-size: 1rem; color: #36454F; display: block; margin-bottom: 1px; }
  .sb-print-brand { font-size: 0.8rem; color: #888; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 10px; }
  .sb-print-sheet .sb-print-meta { color: #666; font-size: 0.85rem; margin-bottom: 24px; }
  .sb-print-ref { color: #666; font-size: 0.8rem; margin-top: 28px; padding-top: 14px; border-top: 1px solid #ddd; }
  .sb-print-ref strong { color: #36454F; letter-spacing: 0.03em; }
  .sb-print-room-title { font-family: var(--font-display); font-size: 1.2rem; margin: 26px 0 12px; padding-top: 14px; border-top: 1px solid #ddd; }
  .sb-print-room-title:first-of-type { border-top: none; padding-top: 0; margin-top: 0; }
  .sb-print-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
  .sb-print-item { break-inside: avoid; }
  .sb-print-swatch { width: 100%; height: 90px; border-radius: 4px; background-size: cover; background-position: center; border: 1px solid #ddd; background-color: #eee; }
  .sb-print-item strong { display: block; margin-top: 6px; font-size: 0.85rem; }
  .sb-print-item span { display: block; font-size: 0.75rem; color: #666; }
}


/* =========================================================
   Catalogue-driven pages
   Colour search, colour detail, wallpaper collections, the
   tools, the sample request form and shared swatch books.
   ========================================================= */

/* Keeps a proper noun from breaking across lines — brand names, mostly. */
.nowrap { white-space: nowrap; }

/* ---- Breadcrumbs ---- */
.crumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding-top: 22px;
  font-size: 0.78rem; color: var(--ink-soft);
}
.crumbs a { border-bottom: 1px solid transparent; }
.crumbs a:hover { color: var(--accent-deep); border-color: var(--accent); }
.crumbs .crumb-sep { opacity: 0.45; }
.crumbs [aria-current] { color: var(--ink); font-weight: 600; }

.page-hero-tight { padding: 40px 0 12px; }
.page-hero-tight h1 { max-width: none; }
.section-tight { padding-top: 28px; }

.btn-ghost-light { border-color: rgba(248,244,234,0.4); color: #F8F4EA; }
.btn-ghost-light:hover { border-color: #F8F4EA; background: rgba(248,244,234,0.08); }

/* ---- Shared form controls for the newer pages ---- */
.form-row { margin-bottom: 16px; }
.form-row label,
.form-fieldset legend {
  display: block; font-size: 0.82rem; font-weight: 600;
  margin-bottom: 7px; color: var(--ink);
}
.label-note { font-weight: 400; color: var(--ink-soft); }
.form-row input[type="text"],
.form-row input[type="email"],
.form-row input[type="tel"],
.form-row input[type="number"],
.form-row select,
.form-row textarea {
  width: 100%;
  border: 1px solid var(--line);
  background: var(--card);
  border-radius: 4px;
  padding: 12px 13px;
  font-size: 0.95rem;
  color: var(--ink);
  transition: border-color .2s ease, box-shadow .2s ease;
}
.form-row textarea { resize: vertical; }
.form-row input:focus, .form-row select:focus, .form-row textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(54,69,79,0.18);
}
.form-fieldset { border: none; padding: 0; }
.radio-row {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 0; font-size: 0.92rem; font-weight: 400; cursor: pointer;
}
.radio-row strong { font-weight: 600; }

/* Tick boxes and radios, drawn rather than left to the browser.
   --------------------------------------------------------------------
   Every other control on these forms is styled: the text fields have the
   card's border radius, the selects match, the buttons are charcoal. The
   boxes were the browser's own thirteen-pixel default sitting in the
   middle of that, which reads as something half finished rather than as
   a deliberately plain control. They are also the smallest thing on the
   page to hit, on forms people fill in on a phone.

   Drawn with the input itself rather than a pseudo-element on a sibling
   span, so the control is still the thing the label points at, still
   focusable, and still announced by a screen reader as a checkbox. */
.radio-row input[type="checkbox"],
.radio-row input[type="radio"] {
  appearance: none; -webkit-appearance: none;
  flex: 0 0 auto; margin: 1px 0 0; width: 20px; height: 20px;
  border: 1.5px solid #B9B7B1; border-radius: 5px;
  background: var(--card, #fff);
  display: grid; place-content: center;
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease;
}
.radio-row input[type="radio"] { border-radius: 50%; }

/* The mark itself, scaled from 0 so the change has a moment of movement
   rather than appearing from nowhere. */
.radio-row input[type="checkbox"]::before,
.radio-row input[type="radio"]::before {
  content: ""; transform: scale(0);
  transition: transform .12s ease;
}
.radio-row input[type="checkbox"]::before {
  width: 11px; height: 11px;
  /* A tick, not a filled square: at this size a square reads as "greyed
     out" to about as many people as it reads as "on". */
  clip-path: polygon(14% 45%, 0 60%, 39% 100%, 100% 18%, 85% 4%, 37% 71%);
  background: var(--card, #fff);
}
.radio-row input[type="radio"]::before {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--card, #fff);
}
.radio-row input[type="checkbox"]:checked,
.radio-row input[type="radio"]:checked {
  background: var(--ink, #36454F); border-color: var(--ink, #36454F);
}
.radio-row input[type="checkbox"]:checked::before,
.radio-row input[type="radio"]:checked::before { transform: scale(1); }

.radio-row input[type="checkbox"]:hover,
.radio-row input[type="radio"]:hover { border-color: var(--ink-soft, #5B5E64); }

/* Visible on the control rather than on the row: the row is the whole
   label and a ring around all of it hides which of the two is focused. */
.radio-row input[type="checkbox"]:focus-visible,
.radio-row input[type="radio"]:focus-visible {
  outline: 2px solid var(--ink, #36454F); outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .radio-row input[type="checkbox"],
  .radio-row input[type="radio"],
  .radio-row input[type="checkbox"]::before,
  .radio-row input[type="radio"]::before { transition: none; }
}
.form-status { font-size: 0.9rem; margin-top: 14px; display: none; }
.form-status.show { display: block; padding: 13px 16px; border-radius: 6px; }
.form-status.success { background: rgba(124,138,94,0.15); border: 1px solid var(--sage); color: var(--ink); }
.form-status.error { background: var(--accent-tint); border: 1px solid var(--accent); color: var(--ink); }

/* ---- Colour search toolbar ---- */
.colour-toolbar {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 18px 20px;
  margin-top: 26px;
  box-shadow: var(--shadow-soft);
}
.colour-search { position: relative; display: flex; align-items: center; }
.colour-search svg {
  position: absolute; left: 14px; width: 18px; height: 18px;
  color: var(--ink-soft); pointer-events: none;
}
.colour-search input {
  width: 100%;
  border: 1px solid var(--line);
  background: var(--parchment);
  border-radius: 6px;
  padding: 13px 40px 13px 42px;
  font-size: 1rem; color: var(--ink);
}
.colour-search input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(54,69,79,0.18);
}
.colour-search input::-webkit-search-cancel-button { display: none; }
.colour-search-clear {
  position: absolute; right: 10px;
  width: 26px; height: 26px; border-radius: 50%;
  font-size: 1.1rem; line-height: 1; color: var(--ink-soft);
  display: flex; align-items: center; justify-content: center;
}
.colour-search-clear:hover { background: var(--accent-tint); color: var(--ink); }

.colour-filter-row {
  display: flex; flex-wrap: wrap; gap: 18px;
  margin-top: 16px;
}
.filter-group { display: flex; flex-wrap: wrap; gap: 7px; }
.filter-group-end { margin-left: auto; }
.filter-divider { width: 1px; align-self: stretch; background: var(--line); margin: 0 4px; }
.filter-chip {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 7px 13px;
  font-size: 0.8rem; color: var(--ink-soft);
  background: var(--parchment);
  transition: border-color .2s ease, color .2s ease, background .2s ease;
}
.filter-chip:hover { border-color: var(--accent); color: var(--ink); }
.filter-chip.active { background: var(--ink); border-color: var(--ink); color: #F8F4EA; }
.filter-chip.active .filter-count { color: rgba(248,244,234,0.65); }
.filter-count { font-size: 0.72rem; color: var(--ink-soft); }
.filter-dot {
  width: 11px; height: 11px; border-radius: 50%;
  border: 1px solid rgba(54,69,79,0.2); flex-shrink: 0;
}
.filter-dot-white   { background: #F4F2ED; }
.filter-dot-grey    { background: #A9ABAD; }
.filter-dot-black   { background: #34363A; }
.filter-dot-neutral { background: #CDBFAB; }
.filter-dot-brown   { background: #8A6F55; }
.filter-dot-red     { background: #A8433A; }
.filter-dot-pink    { background: #DFA8AE; }
.filter-dot-orange  { background: #CE7541; }
.filter-dot-yellow  { background: #E0C066; }
.filter-dot-green   { background: #7C8A5E; }
.filter-dot-blue    { background: #5E7C97; }
.filter-dot-purple  { background: #7C6C93; }

.colour-result-bar {
  display: flex; align-items: center; gap: 14px;
  margin-top: 16px; padding-top: 14px;
  border-top: 1px solid var(--line);
  font-size: 0.84rem; color: var(--ink-soft);
}
.colour-result-bar #colour-result-count { font-weight: 600; color: var(--ink); }
.colour-empty {
  text-align: center; padding: 60px 20px;
  font-size: 0.98rem; color: var(--ink-soft);
}
.colour-empty a { border-bottom: 1px solid var(--accent); color: var(--ink); }

.swatch-card-link { display: block; }
.swatch-grid-teaser { grid-template-columns: repeat(8, 1fr); }
.brand-cta-row {
  display: flex; flex-wrap: wrap; gap: 14px; align-items: center;
  margin-top: 28px;
}

/* ---- A single colour ---- */
.colour-hero { padding: 30px 0 10px; }
.colour-hero-grid {
  display: grid; grid-template-columns: minmax(260px, 380px) 1fr;
  gap: 48px; align-items: start;
}
.colour-hero-swatch { position: sticky; top: 30px; }
.colour-hero-block {
  height: 320px; border-radius: 8px;
  background: var(--swatch);
  box-shadow: var(--shadow);
  border: 1px solid rgba(54,69,79,0.08);
}
.colour-add-btn { width: 100%; justify-content: center; margin-top: 14px; }
.colour-add-btn.is-added { background: var(--sage); }
.colour-code {
  margin-top: 8px; font-size: 0.9rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-soft);
}
.colour-facts {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 26px; margin-top: 28px;
  padding: 22px 24px;
  background: var(--card); border-radius: 8px;
  box-shadow: var(--shadow-soft);
}
.colour-facts dt {
  font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-soft); margin-bottom: 4px;
}
/* A <dd> carries a 40px indent by default, which pushed every value out of
   line with the label above it. Zero it so each pair reads as one column. */
.colour-facts dd {
  margin: 0;
  font-family: var(--font-display); font-size: 1.25rem; color: var(--ink);
}
.colour-facts dd a { border-bottom: 1px solid var(--line); }
.colour-facts dd a:hover { border-color: var(--accent); }
.fact-note {
  font-family: var(--font-body); font-size: 0.72rem;
  color: var(--ink-soft); margin-left: 4px;
}
.colour-tint-note {
  margin-top: 16px; padding: 12px 16px;
  background: var(--accent-tint); border-radius: 6px;
  font-size: 0.9rem; color: var(--ink);
}
.colour-lrv-caveat { margin-top: 16px; font-size: 0.84rem; color: var(--ink-soft); }

/* ---- Pairings and close matches ---- */
.pairing-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px;
}
.pairing-card {
  display: flex; flex-direction: column;
  background: var(--card); border-radius: 8px; overflow: hidden;
  box-shadow: var(--shadow-soft);
  transition: transform .25s ease, box-shadow .25s ease;
}
.pairing-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.pairing-swatch { height: 110px; }
.pairing-body { padding: 16px 18px 20px; }
.pairing-role {
  display: block; font-size: 0.68rem; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--accent); font-weight: 600;
  margin-bottom: 6px;
}
.pairing-body strong { display: block; font-family: var(--font-display); font-size: 1.1rem; }
.pairing-meta { display: block; font-size: 0.78rem; color: var(--ink-soft); margin-top: 2px; }
.pairing-body p { font-size: 0.85rem; margin-top: 10px; line-height: 1.5; }

.similar-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 16px; }
.similar-card {
  background: var(--card); border-radius: 6px; overflow: hidden;
  box-shadow: var(--shadow-soft); padding-bottom: 14px;
  transition: transform .25s ease, box-shadow .25s ease;
}
.similar-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.similar-swatch { height: 82px; }
.similar-card strong { display: block; font-size: 0.85rem; padding: 10px 12px 0; }
.similar-card span { display: block; font-size: 0.72rem; color: var(--ink-soft); padding: 0 12px; }
.similar-delta { margin-top: 5px; color: var(--accent) !important; font-weight: 600; }

/* ---- Tools ---- */
/* Two across, not three.
   ---------------------------------------------------------------------
   There are four tools. In a three-column grid that is a full row and then
   one lone card with two empty cells beside it, which reads as a card
   missing rather than as a deliberate layout. Four across would fix the
   orphan but leaves each card 265px wide at this container size, and
   "Match a colour from a photo" does not sit in 265px without breaking
   awkwardly. Two gives an even 2x2 block and 551px a card.

   If a fifth tool is ever added, three columns becomes the right answer
   again and this rule is the one to revisit. */
.tool-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px; }
/* Two columns hold down to a small tablet. It used to fall to one at
   1024px, which wasted half the width on anything bigger than a phone. */
@media (max-width: 780px) { .tool-grid { grid-template-columns: 1fr; } }
.tool-card {
  display: flex; flex-direction: column; gap: 10px;
  background: var(--card); border-radius: 10px;
  padding: 30px 28px 26px;
  box-shadow: var(--shadow-soft);
  transition: transform .25s ease, box-shadow .25s ease;
}
.tool-card:hover { transform: translateY(-5px); box-shadow: var(--shadow); }
.tool-icon { width: 34px; height: 34px; color: var(--accent); }
.tool-card h2 { font-size: 1.3rem; }
.tool-card p { font-size: 0.92rem; }
.tool-card .text-link { margin-top: auto; padding-top: 12px; align-self: flex-start; }

.calc-layout { display: grid; grid-template-columns: 1.15fr 1fr; gap: 40px; align-items: start; }
.calc-form {
  background: var(--card); border-radius: 10px;
  padding: 28px 30px; box-shadow: var(--shadow-soft);
}
.calc-form h2 { font-size: 1.1rem; margin-bottom: 14px; }
.calc-form h2 + .calc-row-2 { margin-top: 0; }
.calc-form h2:not(:first-child) { margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--line); }
.calc-row-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }

.calc-result {
  position: sticky; top: 26px;
  background: var(--ink); color: #F8F4EA;
  border-radius: 10px; padding: 30px 30px 34px;
}
.calc-result h2 { color: #F8F4EA; font-size: 1.15rem; }
.calc-result h3 {
  color: rgba(248,244,234,0.75); font-family: var(--font-body);
  font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase;
  margin-top: 24px; margin-bottom: 10px;
}
.calc-headline { font-family: var(--font-display); font-size: 2.6rem; line-height: 1.1; color: #F8F4EA; margin-top: 8px; }
.calc-sub { font-size: 0.86rem; color: rgba(248,244,234,0.7); margin-top: 8px; }
.calc-placeholder { font-size: 0.92rem; color: rgba(248,244,234,0.7); }

/* The offer at the foot of the answer. On the website this is a button to
   the contact page; on the panel in the shop it is this sentence, because
   the kiosk must not send anybody out to the website. It had no rule of
   its own and was inheriting a muted body colour, which left the one line
   asking somebody to come to the counter as the faintest thing on the
   panel. It is a call to action, so it is lit like one. */
.calc-ask {
  margin-top: 22px; padding-top: 18px;
  border-top: 1px solid rgba(248,244,234,0.15);
  color: #F8F4EA; font-size: 0.95rem;
}

/* What stands where a calculator was, while it is switched off. Dark like
   the answer panel it replaces, so the page keeps its one weighted block
   rather than gaining a hole, and centred because there is nothing beside
   it any more to line up with. */
.calc-off {
  background: var(--ink); color: #F8F4EA;
  border-radius: 10px; padding: 46px 32px 50px;
  text-align: center; max-width: 620px; margin: 0 auto;
}
.calc-off h2 { color: #F8F4EA; font-size: 1.5rem; }
.calc-off p { margin-top: 12px; color: rgba(248,244,234,0.78); }
.calc-off-ask {
  margin-top: 20px; padding-top: 18px;
  border-top: 1px solid rgba(248,244,234,0.15);
  font-size: 0.9rem;
}

.calc-breakdown { margin-top: 8px; }
.calc-breakdown dl { display: flex; flex-direction: column; gap: 7px; }
.calc-breakdown dl > div { display: flex; justify-content: space-between; gap: 16px; font-size: 0.84rem; }
.calc-breakdown dt { color: rgba(248,244,234,0.65); }
.calc-breakdown dd { color: #F8F4EA; }
.calc-result .btn { margin-top: 26px; }
.calc-result .btn-primary { background: #F8F4EA; color: var(--ink); }
.calc-result .btn-primary:hover { background: #fff; }

/* ---- Colour match ---- */
.match-dropzone {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  border: 2px dashed var(--line); border-radius: 12px;
  padding: 56px 24px; text-align: center;
  background: var(--card); cursor: pointer;
  transition: border-color .2s ease, background .2s ease;
}
.match-dropzone:hover, .match-dropzone.is-over { border-color: var(--accent); background: var(--accent-tint); }
.match-dropzone svg { width: 40px; height: 40px; color: var(--accent); margin-bottom: 4px; }
.match-dropzone strong { font-family: var(--font-display); font-size: 1.25rem; }
.match-dropzone span { font-size: 0.85rem; color: var(--ink-soft); }
/* Dropping a file is a thing you can only do with a mouse, so the line
   about it is only shown to people who have one. Pointer: fine is the
   test that actually means "mouse or trackpad" — a width breakpoint would
   hide it on a small window on a laptop, where it still works. */
.match-drop-hint { display: none; }
@media (pointer: fine) { .match-drop-hint { display: block; } }
.match-example { margin-top: 10px; font-size: 0.85rem; }

.match-workspace {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 36px; align-items: start;
}
.match-image-wrap { position: sticky; top: 26px; }
.match-canvas-frame {
  border-radius: 10px; overflow: hidden;
  box-shadow: var(--shadow); background: var(--parchment-deep);
  line-height: 0;
}
#match-canvas { width: 100%; height: auto; display: block; cursor: crosshair; }
.match-hint {
  display: flex; align-items: center; gap: 8px;
  margin-top: 12px; font-size: 0.85rem; color: var(--ink-soft);
}
.match-hint svg { width: 17px; height: 17px; flex-shrink: 0; color: var(--accent); }
.match-image-wrap .btn { margin-top: 14px; }
.match-status { margin-top: 16px; font-size: 0.88rem; color: var(--ink-soft); }

.match-panel h2 { font-size: 1.35rem; }
.match-panel-note { font-size: 0.85rem; margin-top: 4px; }

.match-palette {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 8px; margin: 16px 0 24px;
}
.palette-chip {
  display: flex; align-items: center; gap: 10px;
  padding: 8px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--card);
  text-align: left;
  transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.palette-chip:hover { border-color: var(--accent); transform: translateY(-1px); }
.palette-chip.is-active {
  border-color: var(--ink);
  box-shadow: 0 0 0 2px var(--ink);
}
.palette-chip-swatch {
  width: 38px; height: 38px; border-radius: 5px; flex-shrink: 0;
  border: 1px solid rgba(54,69,79,0.14);
}
.palette-chip-label {
  display: flex; flex-direction: column; min-width: 0;
  font-size: 0.74rem; letter-spacing: 0.02em; color: var(--ink);
}
.palette-chip-label strong { font-size: 0.8rem; }
.palette-chip-label small { color: var(--ink-soft); font-size: 0.68rem; }

.match-detail-head {
  display: flex; align-items: center; gap: 10px;
  font-size: 1.05rem; margin-bottom: 14px;
  padding-top: 20px; border-top: 1px solid var(--line);
}
.match-detail-swatch {
  width: 28px; height: 28px; border-radius: 5px;
  border: 1px solid rgba(54,69,79,0.14);
}
.match-detail-head code {
  font-size: 0.85rem; color: var(--ink-soft);
  font-family: var(--font-body); letter-spacing: 0.04em;
}

.match-options { display: flex; flex-direction: column; gap: 10px; }
.match-option {
  display: flex; align-items: center; gap: 12px;
  background: var(--card); border-radius: 8px;
  padding: 12px 14px; box-shadow: var(--shadow-soft);
  transition: transform .2s ease, box-shadow .2s ease;
}
.match-option:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.match-option-main { display: flex; align-items: center; gap: 14px; flex: 1; min-width: 0; }
.match-option-swatch {
  width: 58px; height: 58px; border-radius: 6px; flex-shrink: 0;
  border: 1px solid rgba(54,69,79,0.14);
}
.match-option-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.match-option-body strong { font-size: 1rem; }
.match-option-brand { font-size: 0.78rem; color: var(--ink-soft); }
.match-meter {
  display: block; width: 92px; height: 4px; margin-top: 5px;
  background: var(--parchment-deep); border-radius: 2px; overflow: hidden;
}
.match-meter i { display: block; height: 100%; background: var(--accent); }
.match-option-delta { font-size: 0.74rem; font-weight: 600; color: var(--accent); margin-top: 3px; }
.match-add {
  flex-shrink: 0; align-self: center;
  border: 1px solid var(--line); border-radius: 999px;
  padding: 8px 14px; font-size: 0.76rem; font-weight: 600;
  color: var(--ink-soft); background: var(--parchment);
  transition: border-color .2s ease, color .2s ease, background .2s ease;
}
.match-add:hover { border-color: var(--ink); color: var(--ink); }
.match-add.is-added { background: var(--sage); border-color: var(--sage); color: #fff; }
.match-detail-note {
  margin-top: 18px; padding-top: 14px;
  border-top: 1px solid var(--line);
  font-size: 0.82rem; color: var(--ink-soft);
}
.match-detail-note a { color: var(--ink); border-bottom: 1px solid var(--accent); }

@media (max-width: 900px) {
  .match-option { flex-wrap: wrap; }
  .match-add { width: 100%; text-align: center; }
}

/* ---- Sample requests ---- */
.sample-layout { display: grid; grid-template-columns: 1.15fr 1fr; gap: 40px; align-items: start; }
.sample-form {
  background: var(--card); border-radius: 10px;
  padding: 30px 32px; box-shadow: var(--shadow-soft);
}
.sample-form h2 { font-size: 1.1rem; margin-bottom: 16px; }
.sample-form > .btn { margin-top: 18px; }
.sample-aside { position: sticky; top: 26px; }
.sample-aside h2 { font-size: 1.1rem; margin-bottom: 14px; }
.sample-items { display: flex; flex-direction: column; gap: 8px; }
.sample-item {
  display: flex; align-items: center; gap: 12px;
  background: var(--card); border-radius: 6px; padding: 9px 12px;
  box-shadow: var(--shadow-soft);
}
.sample-item-swatch {
  width: 36px; height: 36px; border-radius: 4px; flex-shrink: 0;
  background-size: cover; background-position: center;
  border: 1px solid rgba(54,69,79,0.12);
}
.sample-item-body { display: flex; flex-direction: column; min-width: 0; }
.sample-item-body strong { font-size: 0.88rem; }
.sample-item-body span { font-size: 0.75rem; color: var(--ink-soft); }
.sample-empty { font-size: 0.92rem; color: var(--ink-soft); }
.sample-empty a { border-bottom: 1px solid var(--accent); color: var(--ink); }

/* ---- Shared swatch book ---- */
.book-layout { display: grid; grid-template-columns: 1fr 320px; gap: 40px; align-items: start; }
.book-room-title {
  font-size: 1.3rem; margin: 26px 0 14px;
  padding-top: 18px; border-top: 1px solid var(--line);
}
.book-room-title:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.book-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 16px; }
.book-item {
  background: var(--card); border-radius: 6px; overflow: hidden;
  box-shadow: var(--shadow-soft); padding-bottom: 12px;
}
.book-item-swatch { height: 84px; background-size: cover; background-position: center; }
.book-item strong { display: block; font-size: 0.84rem; padding: 10px 12px 0; }
.book-item span { display: block; font-size: 0.72rem; color: var(--ink-soft); padding: 0 12px; }

.book-aside { position: sticky; top: 26px; display: flex; flex-direction: column; gap: 16px; }
.book-card {
  background: var(--card); border-radius: 10px;
  padding: 24px 26px; box-shadow: var(--shadow-soft);
}
.book-card h3 { font-size: 1.05rem; margin-bottom: 8px; }
.book-card p { font-size: 0.88rem; }
.book-card .btn { margin-top: 14px; }
.book-card-quiet { background: var(--parchment-deep); box-shadow: none; }
.book-qr { display: block; margin: 16px auto 10px; width: 150px; height: 150px; }
.book-share-url {
  font-size: 0.74rem; color: var(--ink-soft);
  word-break: break-all; text-align: center;
}
.book-expiry { margin-top: 12px; font-size: 0.78rem; color: var(--ink-soft); }

/* ---- Swatch book panel: the samples button ---- */
.sb-samples-btn { text-align: center; }

/* =========================================================
   Responsive
   ========================================================= */
@media (max-width: 1024px) {
  .swatch-grid, .swatch-grid-teaser { grid-template-columns: repeat(5, 1fr); }
  .similar-grid { grid-template-columns: repeat(3, 1fr); }
  .pairing-grid { grid-template-columns: repeat(2, 1fr); }
  .calc-layout, .sample-layout, .match-workspace, .book-layout { grid-template-columns: 1fr; }
  .calc-result, .sample-aside, .book-aside, .match-image-wrap, .colour-hero-swatch { position: static; }
  .colour-hero-grid { grid-template-columns: 1fr; gap: 30px; }
  .colour-hero-block { height: 220px; }
  .book-grid { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 720px) {
  .swatch-grid, .swatch-grid-teaser { grid-template-columns: repeat(3, 1fr); }
  .similar-grid, .pairing-grid, .book-grid { grid-template-columns: repeat(2, 1fr); }
  .calc-row-2 { grid-template-columns: 1fr; }
  .colour-facts { grid-template-columns: 1fr; }
  .filter-group-end { margin-left: 0; }
  .colour-toolbar { padding: 14px; }
  .crumbs { font-size: 0.72rem; }
}

/* =========================================================
   Print: the reference block now carries a QR code
   ========================================================= */
@media print {
  .sb-print-ref {
    display: flex; gap: 16px; align-items: flex-start;
    color: #666; font-size: 0.78rem;
    margin-top: 28px; padding-top: 14px; border-top: 1px solid #ddd;
    break-inside: avoid;
  }
  .sb-print-qr { width: 110px; height: 110px; flex-shrink: 0; }
  .sb-print-ref-text p { margin: 0 0 6px; }
  .sb-print-ref-text p:last-child { margin-bottom: 0; }
  .sb-print-url { font-family: monospace; color: #36454F; }
}

/* ---- Tool disclaimers ---- */
.disclaimer {
  background: var(--card);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  padding: 30px 36px 32px;
}
.disclaimer h2 { font-size: 1.35rem; margin-bottom: 12px; }
/* Prose stays at a readable measure; the card itself spans the page so it
   doesn't sit in the left half with a gap beside it. */
.disclaimer p { font-size: 0.92rem; max-width: 96ch; }
.disclaimer ul {
  margin: 14px 0 4px;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 44px;
}
.disclaimer li { break-inside: avoid; }
@media (max-width: 860px) {
  .disclaimer { padding: 24px 22px 26px; }
  .disclaimer ul { grid-template-columns: 1fr; }
}
.disclaimer li {
  font-size: 0.9rem; color: var(--ink-soft);
  padding-left: 18px; position: relative; line-height: 1.55;
}
.disclaimer li::before {
  content: ""; position: absolute; left: 0; top: 0.62em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--accent);
}
.disclaimer strong { color: var(--ink); }
.disclaimer-close {
  margin-top: 18px; padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: 0.9rem;
}
.disclaimer-close a { border-bottom: 1px solid var(--accent); color: var(--ink); }

.calc-caveat {
  margin-top: 14px; padding-top: 12px;
  border-top: 1px solid rgba(248,244,234,0.15);
  font-size: 0.78rem; color: rgba(248,244,234,0.65); line-height: 1.5;
}
.calc-caveat a { color: rgba(248,244,234,0.9); border-bottom: 1px solid rgba(248,244,234,0.4); }

/* ---- Brand hero on the colour and wallpaper brand pages ---- */
.brand-hero-below {
  margin-top: 26px; padding-top: 22px;
  border-top: 1px solid var(--line);
}
.brand-hero-blurb { max-width: none; }
.brand-hero-links {
  display: flex; flex-wrap: wrap; gap: 22px;
  margin-top: 14px;
}

/* ---- Wallpaper modal footer ---- */
.wp-modal-foot {
  padding: 14px 22px 18px;
  border-top: 1px solid var(--line);
  flex-shrink: 0;
}
.wp-modal-foot:empty { display: none; }

/* =========================================================
   Brand hero — the compact version used on the colour and
   wallpaper brand pages. The brand story page keeps the
   larger original proportions.
   ========================================================= */
.page-hero-brand { padding: 34px 0 30px; }
.page-hero-brand h1 { font-size: clamp(1.8rem, 3vw, 2.5rem); }
.page-hero-brand .eyebrow { margin-bottom: 10px; }
.page-hero-brand .brand-hero { gap: 24px; }
.page-hero-brand .brand-hero-logo {
  max-width: 140px; max-height: 140px; padding: 16px;
}
.page-hero-brand .brand-hero .lede { font-size: 1rem; margin-top: 8px !important; }
.page-hero-brand .brand-tabs { margin-top: 18px; }
.page-hero-brand .brand-tab { padding: 8px 18px; font-size: 0.84rem; }
.page-hero-brand .chip-crossfade { width: 170px; height: 170px; }
.page-hero-brand .paint-chip .chip-info { padding: 11px 13px 13px; }
.page-hero-brand .chip-num { font-size: 0.66rem; }
.page-hero-brand .chip-name { font-size: 0.86rem; }
.page-hero-brand .brand-hero-below { margin-top: 20px; padding-top: 18px; }
.page-hero-brand .brand-hero-blurb { font-size: 1rem; }

/* A wallpaper chip shows the paper itself rather than a flat colour. */
.chip-swatch-image {
  background-size: cover;
  background-position: center;
  background-color: var(--parchment-deep);
}

@media (max-width: 900px) {
  .page-hero-brand .brand-hero-logo { max-width: 96px; max-height: 96px; padding: 12px; }
  .page-hero-brand .brand-hero { gap: 18px; }
}

/* ------------------------------------------------------------------
   Cookie / measurement notice
   ------------------------------------------------------------------
   A bar rather than a modal: it doesn't block the page, doesn't dim the
   site behind it, and can be ignored while the visitor reads. Both
   answers are the same size and weight, side by side, because a notice
   where "no" is harder to give than "yes" isn't really a question. */
.cookie-notice {
  position: fixed;
  left: 16px; right: 16px; bottom: 16px;
  z-index: 9000;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(54,69,79,0.18);
  transform: translateY(140%);
  opacity: 0;
  transition: transform .3s ease, opacity .3s ease;
  max-width: 940px;
  margin: 0 auto;
}
.cookie-notice.is-in { transform: translateY(0); opacity: 1; }

.cookie-notice-inner {
  display: flex; align-items: center; gap: 28px;
  padding: 18px 22px;
}
.cookie-notice-text strong {
  display: block;
  font-family: var(--font-display);
  font-size: 1.02rem;
  margin-bottom: 4px;
}
.cookie-notice-text p {
  margin: 0;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.cookie-notice-text a { border-bottom: 1px solid var(--line); }
.cookie-notice-text a:hover { border-color: var(--accent); }

.cookie-notice-actions {
  display: flex; gap: 10px; flex-shrink: 0;
}
.cookie-notice-actions .btn {
  padding: 10px 20px;
  font-size: 0.9rem;
  white-space: nowrap;
}
.btn-outline {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line);
}
.btn-outline:hover { border-color: var(--ink); }

@media (max-width: 720px) {
  .cookie-notice { left: 10px; right: 10px; bottom: 10px; }
  .cookie-notice-inner { flex-direction: column; align-items: stretch; gap: 16px; padding: 18px; }
  .cookie-notice-actions .btn { flex: 1 1 0; justify-content: center; }
}

/* Respect a system-level request for less motion. */
@media (prefers-reduced-motion: reduce) {
  .cookie-notice { transition: opacity .2s ease; transform: none; }
}

/* ------------------------------------------------------------------
   Paper and paint, paired
   ------------------------------------------------------------------
   Wallpapers matched to a paint colour, and paints matched to a paper.
   Both are derived from photographs of the papers, so both carry the
   .match-caveat line underneath — see al_match_disclaimer(). */
.paper-pair-grid, .paint-pair-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 20px;
}
.paper-pair-card, .paint-pair-card {
  background: var(--card); border-radius: 8px; overflow: hidden;
  box-shadow: var(--shadow-soft);
  transition: transform .2s ease, box-shadow .2s ease;
}
.paper-pair-card:hover, .paint-pair-card:hover {
  transform: translateY(-4px); box-shadow: var(--shadow);
}
.paper-pair-image { position: relative; height: 160px; overflow: hidden; }
.paper-pair-image img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* The dot is the colour in the paper that actually matched — it makes the
   claim checkable rather than asking the visitor to take it on trust. */
.paper-pair-swatch {
  position: absolute; right: 10px; bottom: 10px;
  width: 32px; height: 32px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,0.92);
  /* A hairline outside the white ring as well, so the disc still reads when
     the matched colour is nearly the colour of the paper behind it — which,
     given it matched, is the usual case. */
  box-shadow: 0 0 0 1px rgba(54,69,79,0.30), 0 1px 6px rgba(54,69,79,0.28);
}

.paint-pair-swatch { position: relative; height: 118px; }
.paint-pair-share {
  position: absolute; left: 10px; bottom: 9px;
  font-size: .68rem; letter-spacing: .08em;
  padding: 2px 7px; border-radius: 10px;
  background: rgba(255,255,255,0.92); color: var(--ink);
}

.paper-pair-body, .paint-pair-body { padding: 13px 15px 15px; }
.paper-pair-body strong, .paint-pair-body strong {
  display: block; font-family: var(--font-display); font-size: 1.02rem; margin-bottom: 2px;
}
.paper-pair-body span, .paint-pair-body span {
  display: block; font-size: .82rem; color: var(--ink-soft);
}
.paper-pair-note, .paint-pair-note { margin-top: 6px; font-size: .78rem !important; }

.match-caveat {
  margin-top: 26px;
  font-size: .85rem;
  color: var(--ink-soft);
  line-height: 1.6;
  max-width: 74ch;
  padding-left: 14px;
  border-left: 2px solid var(--line);
}

/* ------------------------------------------------------------------
   Inspiration schemes
   ------------------------------------------------------------------ */
.scheme-grid {
  display: grid;
  /* Four to a row on a full-width screen, stepping down rather than letting
     auto-fill decide — a scheme card wants to be seen next to its siblings,
     and three-across left an awkward gap at this page width. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 24px;
}
@media (max-width: 1080px) { .scheme-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 820px)  { .scheme-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; } }
@media (max-width: 520px)  { .scheme-grid { grid-template-columns: 1fr; } }
.scheme-card {
  background: var(--card); border-radius: 10px; overflow: hidden;
  box-shadow: var(--shadow-soft);
  display: flex; flex-direction: column;
  transition: transform .2s ease, box-shadow .2s ease;
}
.scheme-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.scheme-card-paper { height: 190px; overflow: hidden; }
.scheme-card-paper img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* The strip is the scheme in miniature, at the proportions it would be
   used in — so the card shows the idea, not just a row of swatches. */
.scheme-card-strip { display: flex; height: 32px; }
.scheme-card-body { padding: 17px 19px 19px; }
.scheme-card-body strong {
  display: block; font-family: var(--font-display); font-size: 1.2rem; margin-bottom: 3px;
}
.scheme-card-body span { display: block; font-size: .84rem; color: var(--ink-soft); }
.scheme-card-meta { margin-top: 11px; font-size: .8rem !important; }

/* ---- One scheme ---- */
.scheme-board { display: grid; grid-template-columns: 1.12fr 1fr; gap: 46px; align-items: start; }
.scheme-board-paper { border-radius: 10px; overflow: hidden; box-shadow: var(--shadow-soft); }
.scheme-board-paper img { width: 100%; display: block; }
.scheme-board-cap {
  display: block; padding: 14px 18px;
  background: var(--card); font-size: .85rem; color: var(--ink-soft);
}
.scheme-board-cap strong {
  display: block; color: var(--ink);
  font-family: var(--font-display); font-size: 1.02rem; margin-bottom: 2px;
}
.scheme-board-cap:hover strong { color: var(--accent); }

.scheme-proportion {
  display: flex; height: 92px; margin: 26px 0 12px;
  border-radius: 8px; overflow: hidden; box-shadow: var(--shadow-soft);
}
.scheme-proportion div { min-width: 0; }

/* The key, under the bar. See al_scheme_proportions() for why the labels
   are not inside the bands. */
.scheme-proportion-key {
  display: flex; flex-wrap: wrap; gap: 8px 22px;
  list-style: none; margin: 0 0 12px; padding: 0;
}
.scheme-proportion-key li {
  display: flex; align-items: center; gap: 8px;
  font-size: .68rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft); white-space: nowrap;
}
.scheme-key-chip {
  width: 13px; height: 13px; border-radius: 3px; flex-shrink: 0;
  box-shadow: inset 0 0 0 1px rgba(54,69,79,.14);
}
.prop-note { font-size: .82rem; color: var(--ink-soft); line-height: 1.6; }

.scheme-role {
  display: flex; gap: 16px; align-items: center;
  padding: 17px 0; border-bottom: 1px solid var(--line);
}
.scheme-role:first-child { padding-top: 0; }
.scheme-role-chip {
  width: 78px; height: 78px; border-radius: 8px; flex-shrink: 0;
  box-shadow: inset 0 0 0 1px rgba(54,69,79,0.08);
  transition: transform .15s ease;
}
.scheme-role-chip:hover { transform: scale(1.04); }
.scheme-role-label {
  font-size: .7rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-soft); margin-bottom: 3px;
}
.scheme-role-name { font-family: var(--font-display); font-size: 1.14rem; }
.scheme-role-name a:hover { color: var(--accent); }
.scheme-role-brand { font-size: .82rem; color: var(--ink-soft); margin-bottom: 5px; }
.scheme-role-note { font-size: .84rem; color: var(--ink-soft); line-height: 1.5; }

.scheme-actions { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 26px; }

@media (max-width: 900px) {
  .scheme-board { grid-template-columns: 1fr; gap: 30px; }
  .scheme-proportion { height: 74px; }
}
#scheme-add.is-added { background: var(--sage); }

/* ------------------------------------------------------------------
   The installable app
   ------------------------------------------------------------------ */
.book-toolbar {
  display: flex; justify-content: space-between; align-items: center;
  gap: 20px; flex-wrap: wrap; margin-bottom: 30px;
  padding-bottom: 20px; border-bottom: 1px solid var(--line);
}
.book-count { font-size: 1.05rem; }
.book-count strong { font-family: var(--font-display); font-size: 1.5rem; }
.book-offline-state {
  display: inline-block; margin-left: 12px;
  font-size: .74rem; letter-spacing: .06em; text-transform: uppercase;
  padding: 3px 10px; border-radius: 12px;
  background: var(--sage, #6E7F6B); color: #fff;
}
.book-toolbar-actions { display: flex; gap: 10px; flex-wrap: wrap; }

.book-room { margin-bottom: 38px; }
.book-room-name {
  font-family: var(--font-display); font-size: 1.2rem; margin-bottom: 14px;
}
.book-item-row {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 16px;
}
.book-card { background: var(--card); border-radius: 8px; overflow: hidden; box-shadow: var(--shadow-soft); }
.book-card-swatch {
  display: block; height: 104px;
  background-size: cover; background-position: center;
}
.book-card-name { display: block; padding: 11px 13px 0; font-weight: 600; font-size: .92rem; }
.book-card-meta { display: block; padding: 2px 13px 13px; font-size: .8rem; color: var(--ink-soft); }
.book-empty { text-align: center; padding: 40px 0 60px; }
.book-footnote { margin-top: 30px; font-size: .84rem; color: var(--ink-soft); }

/* ---- Handoff ---- */
.handoff-overlay {
  position: fixed; inset: 0; z-index: 9500;
  background: rgba(28,30,34,.55);
  display: flex; align-items: center; justify-content: center; padding: 20px;
  opacity: 0; transition: opacity .25s ease;
}
.handoff-overlay.is-in { opacity: 1; }
.handoff-card {
  position: relative; background: var(--card); border-radius: 14px;
  padding: 34px 32px; max-width: 400px; width: 100%; text-align: center;
  box-shadow: 0 24px 60px -18px rgba(28,30,34,.45);
}
.handoff-card h2 { font-family: var(--font-display); font-size: 1.4rem; margin-bottom: 8px; }
.handoff-card p { font-size: .9rem; color: var(--ink-soft); line-height: 1.55; }
.handoff-qr {
  display: block; margin: 22px auto 16px; border-radius: 8px;
  background: #fff; padding: 10px;
}
.handoff-ref { font-size: .9rem !important; color: var(--ink) !important; }
.handoff-ref strong { font-family: ui-monospace, Menlo, Consolas, monospace; letter-spacing: .05em; }
.handoff-note { margin-top: 14px; font-size: .78rem !important; }
.handoff-link { margin-top: 18px; }
.handoff-close {
  position: absolute; top: 10px; right: 14px;
  font-size: 26px; line-height: 1; color: var(--ink-soft);
}

/* ---- Counter view: legible from the other side of a counter ---- */
.counter-overlay {
  position: fixed; inset: 0; z-index: 9600; background: var(--parchment);
  overflow-y: auto; padding: 0 0 40px;
}
.counter-head {
  position: sticky; top: 0; z-index: 2;
  display: flex; justify-content: space-between; align-items: flex-start;
  padding: 22px 24px; background: var(--ink); color: #F8F4EA;
}
.counter-eyebrow { font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; opacity: .8; }
/* The colour is not optional here. style.css gives every heading its own
   dark ink, which beats anything inherited — so on this dark header the
   title was rendering ink-on-ink and simply was not there. */
.counter-head h2 {
  font-family: var(--font-display); font-size: 1.5rem; margin-top: 4px;
  color: #F8F4EA;
}
.counter-close { font-size: 32px; line-height: 1; color: #F8F4EA; }
.counter-body { padding: 22px 24px; display: grid; gap: 14px; }
.counter-item {
  display: flex; gap: 18px; align-items: center;
  background: var(--card); border-radius: 10px; padding: 14px;
  box-shadow: var(--shadow-soft);
}
.counter-swatch {
  width: 92px; height: 92px; border-radius: 8px; flex-shrink: 0;
  background-size: cover; background-position: center;
  box-shadow: inset 0 0 0 1px rgba(54,69,79,.1);
}
.counter-item strong { display: block; font-family: var(--font-display); font-size: 1.35rem; }
.counter-item span { display: block; font-size: 1rem; color: var(--ink-soft); margin-top: 2px; }

/* ---- Install invitation ---- */
.install-tip {
  position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 9000;
  max-width: 680px; margin: 0 auto;
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 8px 32px rgba(54,69,79,.18);
  transform: translateY(140%); opacity: 0;
  transition: transform .3s ease, opacity .3s ease;
}
.install-tip.is-in { transform: translateY(0); opacity: 1; }
.install-tip-inner { display: flex; align-items: center; gap: 24px; padding: 18px 22px; }
.install-tip-text strong { display: block; font-family: var(--font-display); font-size: 1.02rem; margin-bottom: 3px; }
.install-tip-text p { margin: 0; font-size: .86rem; color: var(--ink-soft); }
.install-tip-actions { display: flex; gap: 10px; flex-shrink: 0; }

/* Running as an installed app: the site header is the app's chrome, so it
   loses the "visit us" call to action that belongs on a marketing page. */
.is-app .nav-actions .btn-primary { display: none; }

@media (max-width: 720px) {
  .install-tip-inner { flex-direction: column; align-items: stretch; gap: 14px; }
  .install-tip-actions .btn { flex: 1 1 0; justify-content: center; }
  .counter-swatch { width: 74px; height: 74px; }
}
@media (prefers-reduced-motion: reduce) {
  .install-tip, .handoff-overlay { transition: opacity .2s ease; transform: none; }
}

/* ---- The install bar and the iOS instructions ---- */
.install-tip-icon { border-radius: 10px; flex-shrink: 0; }
.install-tip-inner { align-items: center; }

.ios-install {
  position: fixed; inset: 0; z-index: 9700;
  background: rgba(28,30,34,.55);
  display: flex; align-items: flex-end; justify-content: center;
  opacity: 0; transition: opacity .25s ease;
}
.ios-install.is-in { opacity: 1; }
.ios-install-card {
  position: relative; width: 100%; max-width: 460px;
  background: var(--card);
  border-radius: 16px 16px 0 0;
  padding: 28px 26px calc(26px + env(safe-area-inset-bottom, 0px));
  transform: translateY(30px); transition: transform .28s ease;
}
.ios-install.is-in .ios-install-card { transform: translateY(0); }
.ios-install-card h2 { font-family: var(--font-display); font-size: 1.3rem; margin-bottom: 18px; }
.ios-install-close {
  position: absolute; top: 12px; right: 16px;
  font-size: 26px; line-height: 1; color: var(--ink-soft);
}
.ios-install-steps { list-style: none; margin: 0 0 18px; padding: 0; }
.ios-install-steps li {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 0; font-size: .95rem;
  border-bottom: 1px solid var(--line);
}
.ios-install-steps li:last-child { border-bottom: none; }
/* The li is a flex row, so the sentence needs to be one item rather
   than a handful of text nodes and <strong>s fighting for the width. */
.ios-step-text { min-width: 0; }
.ios-step-icon {
  width: 40px; height: 40px; border-radius: 10px; flex-shrink: 0;
  background: var(--parchment);
  display: flex; align-items: center; justify-content: center;
  color: var(--accent);
}
.ios-step-icon svg { width: 21px; height: 21px; }
.ios-install-note { font-size: .82rem; color: var(--ink-soft); line-height: 1.55; margin-bottom: 18px; }
.ios-install-done { width: 100%; justify-content: center; }

@media (prefers-reduced-motion: reduce) {
  .ios-install, .ios-install-card { transition: opacity .2s ease; transform: none; }
}

/* ------------------------------------------------------------------
   The launch screen
   ------------------------------------------------------------------
   Only ever shown in an installed app, once per launch, for about a
   second. It exists because the operating system's own splash is a
   static image that cannot move — this is the part that can. */
.launch {
  position: fixed; inset: 0; z-index: 10000;
  background: var(--parchment);
  display: flex; align-items: center; justify-content: center;
  opacity: 1;
  transition: opacity .38s ease;
}
.launch.is-out { opacity: 0; pointer-events: none; }

/* The chips wash across the field behind the mark. Big, soft and slow —
   at this size they read as light falling across a wall rather than as
   swatches, which is the intention. */
.launch-chips { position: absolute; inset: 0; overflow: hidden; }
.launch-chips span {
  position: absolute; inset: -12%;
  opacity: 0;
  animation: launch-wash 3.4s ease-in-out infinite;
}
@keyframes launch-wash {
  0%, 100% { opacity: 0; }
  18%, 30% { opacity: .55; }
}

.launch-inner { position: relative; text-align: center; }
.launch-mark {
  width: 132px; height: 132px; border-radius: 50%;
  display: block; margin: 0 auto 26px;
  opacity: 0; transform: scale(.9);
  animation: launch-mark .62s cubic-bezier(.22,.9,.3,1) forwards;
}
@keyframes launch-mark {
  to { opacity: 1; transform: scale(1); }
}

.launch-address, .launch-town {
  opacity: 0;
  animation: launch-line .5s ease forwards;
}
.launch-address {
  font-family: var(--font-display); font-size: 1.12rem; color: var(--ink);
  animation-delay: .26s;
}
.launch-town {
  font-size: .82rem; color: var(--ink-soft); margin-top: 4px;
  letter-spacing: .04em;
  animation-delay: .38s;
}
@keyframes launch-line {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Someone who has asked for less motion gets the same screen, still. */
.launch.is-still .launch-mark,
.launch.is-still .launch-address,
.launch.is-still .launch-town {
  animation: none; opacity: 1; transform: none;
}

/* ---- Bringing a list across from another device ---- */
.book-restore {
  margin: 44px auto 0; max-width: 520px;
  padding-top: 30px; border-top: 1px solid var(--line);
  text-align: left;
}
.book-restore h3 { font-family: var(--font-display); font-size: 1.08rem; margin-bottom: 6px; }
.book-restore p { font-size: .88rem; color: var(--ink-soft); line-height: 1.55; }
.book-restore-form { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.book-restore-form input {
  flex: 1 1 180px; min-width: 0;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: 8px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  letter-spacing: .06em; text-transform: uppercase;
  background: var(--card);
}
.book-restore-form input:focus { outline: 2px solid var(--ink); outline-offset: 1px; }
.book-restore-status { margin-top: 12px; font-size: .86rem; min-height: 1.2em; }
.book-restore-status.is-ok  { color: var(--sage, #4C6A4E); }
.book-restore-status.is-bad { color: var(--danger, #A6423A); }

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

/* "My Swatch Book" in the menu.
   Hidden on a wide screen because the floating swatch-book button is always
   visible there; inside a phone's menu it is the only signpost to the page. */
.nav-swatch-link { display: none; }
@media (max-width: 900px) {
  .nav-swatch-link { display: block; }
  .nav-links.open .nav-swatch-link {
    color: var(--accent);
    font-weight: 600;
  }
}

/* ------------------------------------------------------------------
   Error pages
   ------------------------------------------------------------------
   A 404 here is usually a half-remembered colour name, so the near
   matches are the main event and get card treatment; the section
   underneath is the fallback for when we guessed wrong. */
.error-suggestions {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 16px;
}
.error-suggestion {
  display: flex; align-items: center; gap: 14px;
  background: var(--card); border-radius: 10px; padding: 12px 14px;
  box-shadow: var(--shadow-soft);
  transition: transform .18s ease, box-shadow .18s ease;
}
.error-suggestion:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.error-suggestion-swatch {
  width: 56px; height: 56px; border-radius: 8px; flex-shrink: 0;
  background-size: cover; background-position: center;
  box-shadow: inset 0 0 0 1px rgba(54,69,79,.1);
}
.error-suggestion-text { min-width: 0; }
.error-suggestion-text strong {
  display: block; font-family: var(--font-display); font-size: 1.02rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.error-suggestion-text small { display: block; font-size: .8rem; color: var(--ink-soft); margin-top: 2px; }

.error-search {
  display: flex; gap: 10px; flex-wrap: wrap;
  max-width: 560px; margin-bottom: 34px;
}
.error-search input {
  flex: 1 1 240px; min-width: 0;
  padding: 13px 16px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--card); font-size: .95rem;
}
.error-search input:focus { outline: 2px solid var(--ink); outline-offset: 1px; }

.error-links {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 14px;
}
.error-link {
  display: block; padding: 18px 20px;
  background: var(--card); border-radius: 10px;
  box-shadow: var(--shadow-soft);
  transition: transform .18s ease, box-shadow .18s ease;
}
.error-link:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.error-link strong {
  display: block; font-family: var(--font-display); font-size: 1.06rem; margin-bottom: 4px;
}
.error-link span { display: block; font-size: .84rem; color: var(--ink-soft); line-height: 1.5; }

/* The swatch book code, on a phone, sized to be read out loud or typed
   into the screen in the shop. Big because it is the whole point of the
   panel there — the QR is no use on the device holding it. */
.handoff-code {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 44px; font-weight: 600; letter-spacing: 0.08em;
  margin: 18px 0; padding: 18px 10px;
  background: var(--parchment-deep, #E9E4DA); border-radius: 12px;
}

/* ---- Sending a photo from a phone to this page ----------------------
   Offered under the file chooser on the colour matcher, for the common
   case where the photo and the browser are on different devices. Hidden
   on touch devices by the script, where it would be offering to send a
   photo from the phone to the phone. */
/* Margin on the bottom as well as the top. With only a top margin this
   card sat flush against the photo and the results below it the moment a
   picture was loaded — the two blocks touching, with nothing between them.
   It is a panel between two other panels and needs air on both sides. */
.match-handoff {
  margin: 18px 0 28px; padding: 20px 22px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--card);
}
.match-handoff[hidden] { display: none; }
.match-handoff-lead { margin: 0 0 14px; font-size: 0.95rem; color: var(--ink-soft); }
.match-handoff-lead strong { display: block; color: var(--ink); font-size: 1rem; }
.match-handoff-live {
  display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 24px; align-items: start;
}
.match-handoff-live[hidden] { display: none; }
@media (max-width: 640px) { .match-handoff-live { grid-template-columns: 1fr; } }
.match-handoff-qr {
  padding: 10px; background: #fff; border: 1px solid var(--line); border-radius: 10px;
}
.match-handoff-qr img { display: block; width: 100%; height: auto; }
.match-handoff-words p { margin: 0 0 12px; font-size: 0.95rem; }
.match-handoff-status { font-weight: 600; color: var(--ink); }
.match-handoff-privacy { font-size: 0.85rem !important; line-height: 1.5; }

/* ---- Which finish? --------------------------------------------------
   A reference list, so it is set as a definition list rather than cards:
   the name and what it is for belong together, and a customer scanning
   for "eggshell" should find it by running down one column.

   NOTE ON THE CLASS NAMES: these are all "finishes-", not "finish-".
   ".finish-list" already exists further up this stylesheet as the swatch
   book's row of finish chips, where it is display:flex — and because the
   block here only set `margin`, the <dl> on this page inherited that flex
   and every row sized itself to its own text (700px, 562px, 804px...),
   which is exactly the ragged mess a column layout exists to prevent. Two
   different components must not share a class name; the plural keeps them
   apart. */
.finishes-jump {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 18px;
  margin: 0 0 34px; padding-bottom: 18px; border-bottom: 1px solid var(--line);
  font-size: .92rem;
}
.finishes-jump span {
  color: var(--ink-soft); text-transform: uppercase;
  letter-spacing: .12em; font-size: .74rem;
}
.finishes-jump a { color: var(--accent-deep); font-weight: 600; }

/* The brand sits in its own column beside its list on a wide screen, so a
   reader partway down a list of twelve still knows whose names these are.
   It stacks on anything narrower. */
.finishes-group {
  display: grid; grid-template-columns: minmax(0, 16rem) minmax(0, 1fr);
  gap: 12px 48px; margin: 0 0 52px;
}
.finishes-group:last-of-type { margin-bottom: 34px; }
.finishes-brand { align-self: start; position: sticky; top: 104px; }
.finishes-brand h2 { font-size: 1.7rem; margin: 0 0 6px; }
.finishes-note { color: var(--ink-soft); margin: 0 0 8px; font-size: .95rem; }
.finishes-count {
  margin: 0; color: var(--ink-soft); font-size: .74rem;
  text-transform: uppercase; letter-spacing: .12em;
}

.finishes-list { margin: 0; }
.finishes-row {
  display: grid; grid-template-columns: minmax(0, 17rem) minmax(0, 1fr);
  gap: 6px 28px; padding: 15px 0; border-top: 1px solid var(--line);
}
.finishes-row:last-child { border-bottom: 1px solid var(--line); }
.finishes-term { margin: 0; }
.finishes-name { display: block; font-weight: 600; color: var(--ink); }
.finishes-use { margin: 0; color: var(--ink-soft); }

/* Only some makers publish a sheen figure, so this is an aside under the
   name rather than a column that would be blank two-fifths of the time. */
.finishes-sheen { display: block; margin-top: 5px; }
.finishes-sheen-figure {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  background: var(--accent-tint); color: var(--ink-soft);
  font-size: .76rem; font-weight: 500; letter-spacing: .02em; white-space: nowrap;
}
/* The bar makes 3% against 40% against 80% legible at a glance, which the
   numbers alone do not manage in a list this long. The layout keeps each
   brand's bars in their own column, because the makers do not measure sheen
   the same way and comparing across them is not sound — the caveat says so. */
.finishes-bar {
  display: block; margin-top: 7px; height: 4px; max-width: 190px;
  border-radius: 999px; background: var(--line); overflow: hidden;
}
.finishes-bar-fill {
  display: block; height: 100%; border-radius: 999px;
  background: var(--accent-deep); min-width: 3px;
}

/* Full width, one column. It was capped at 70ch, which left the box
   stranded with half the page empty beside it. Same reasoning as
   .instore-privacy: the cap is what made it look unfinished, and columns
   are not the answer for a note this short. */
.finishes-caveat {
  margin: 8px 0 0; padding: 22px 26px; border-radius: 12px;
  background: var(--parchment-deep); color: var(--ink-soft); font-size: .97rem;
  line-height: 1.65; text-wrap: pretty;
}

@media (max-width: 900px) {
  .finishes-group { grid-template-columns: 1fr; gap: 4px; margin-bottom: 42px; }
  .finishes-brand { position: static; margin-bottom: 12px; }
}
@media (max-width: 620px) {
  .finishes-row { grid-template-columns: 1fr; gap: 4px; }
}

/* More air around the rule under the hero.
   ---------------------------------------------------------------------
   .page-hero-tight leaves 12px between the lede and the border and
   .section-tight puts 28px under it, so the break between the
   introduction and the page proper was 40px in total and read as cramped.
   Scoped to this page rather than changed on the shared classes, because
   the tools, finishes and inspiration pages use the same pair and nobody
   has asked for those to move. */
.instore-hero { padding-bottom: 36px; }
.instore-section { padding-top: 54px; }
@media (max-width: 700px) {
  .instore-hero { padding-bottom: 26px; }
  .instore-section { padding-top: 38px; }
}

/* ---- In the shop ----------------------------------------------------
   A page about the screen by the counter. Picture-led, because the thing
   being described is a physical object in a shop and the job of the page is
   to get somebody through the door. */

/* The slideshow.
   ---------------------------------------------------------------------
   Without JavaScript every slide is a real figure in the document and this
   is a captioned list of the screens, stacked. .is-live is added by the
   script, and only then does it become a single frame. So the no-script
   version is never a broken slideshow, it is a different and complete
   thing. */
.kioskshow { margin: 0 0 58px; }
.kioskshow-track { display: grid; gap: 26px; justify-items: center; }
.kioskshow-slide { margin: 0; max-width: 340px; }
.kioskshow-slide img {
  display: block; width: 100%; height: auto; border-radius: 16px;
  border: 1px solid var(--line); box-shadow: var(--shadow-soft);
  background: var(--parchment-deep);
}
.kioskshow-slide figcaption { margin-top: 14px; text-align: center; }
.kioskshow-slide figcaption strong {
  display: block; font-family: var(--font-display); font-size: 1.2rem;
}
.kioskshow-slide figcaption span {
  display: block; margin-top: 4px; color: var(--ink-soft); font-size: .95rem;
}

/* ---- Once the script has taken over ---- */
.kioskshow.is-live {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 22px;
  justify-items: center;
}
.kioskshow.is-live .kioskshow-frame {
  position: relative; width: 100%; max-width: 340px;
  /* The frame holds its height so the page does not jump as slides change:
     640x1138 is the shape of the panel in the shop. */
  aspect-ratio: 640 / 1138;
}
.kioskshow.is-live .kioskshow-track {
  display: block; position: absolute; inset: 0;
}
.kioskshow.is-live .kioskshow-slide {
  position: absolute; inset: 0; max-width: none;
  opacity: 0; visibility: hidden;
  transition: opacity .5s ease, visibility 0s linear .5s;
}
.kioskshow.is-live .kioskshow-slide.is-current {
  opacity: 1; visibility: visible;
  transition: opacity .5s ease, visibility 0s linear 0s;
}
.kioskshow.is-live .kioskshow-slide img { height: 100%; object-fit: cover; }
/* The caption sits under the frame rather than inside it, so it never
   covers the screen it is describing. */
.kioskshow.is-live .kioskshow-slide figcaption {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  width: 100%; max-width: 26rem; margin-top: 18px;
}
@media (prefers-reduced-motion: reduce) {
  .kioskshow.is-live .kioskshow-slide { transition: none; }
}

.kioskshow-controls {
  display: flex; align-items: center; gap: 14px;
  /* Clears the absolutely positioned caption above it. */
  margin-top: 108px;
}
.kioskshow-arrow {
  width: 42px; height: 42px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--card);
  font-size: 1.05rem; line-height: 1; color: var(--ink);
  display: flex; align-items: center; justify-content: center;
}
.kioskshow-arrow:hover { border-color: var(--ink); }
.kioskshow-arrow:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.kioskshow-dots { display: flex; align-items: center; gap: 9px; }
.kioskshow-dot {
  width: 9px; height: 9px; padding: 0; border-radius: 50%;
  border: 0; background: var(--line); transition: background .2s, transform .2s;
}
.kioskshow-dot.is-on { background: var(--accent-deep); transform: scale(1.35); }
.kioskshow-dot:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.kioskshow-status {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ---- The rest of the page ---- */
/* The prose runs down the left and the screen itself sits on the right.
   The slideshow used to be a full-width band on its own above this, which
   left an empty strip beside it at every width above a tablet. */
.instore-lead {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
  gap: 56px; margin-bottom: 56px; align-items: start;
}
/* Both prose blocks live in this one grid cell, so the slideshow beside
   them is the second column rather than being pushed onto a row of its
   own by a third grid child. */
.instore-lead-copy { min-width: 0; }
.instore-lead-text h2 { margin: 0 0 12px; font-size: 1.9rem; }
.instore-lead-text h2 + p { margin-top: 0; }
.instore-lead-text p { margin: 0 0 14px; }
.instore-lead-text p:last-child { margin-bottom: 0; }
/* The two prose blocks stack in the left column, with air between them. */
.instore-lead-text + .instore-lead-text { margin-top: 34px; }
/* Sticky, so the picture stays with you while you read the column beside
   it rather than scrolling away at the first heading. */
.instore-lead-show { position: sticky; top: 104px; }

.instore-h { margin: 0 0 20px; font-size: 1.9rem; }
.instore-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px; margin-bottom: 34px;
}
.instore-card {
  padding: 24px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--card);
}
.instore-card h3 { margin: 0 0 8px; font-size: 1.22rem; }
.instore-card p { margin: 0; color: var(--ink-soft); font-size: .96rem; }

/* Full width, one column.
   ---------------------------------------------------------------------
   This went through two wrong versions. First it was capped at 74ch,
   which left an orphaned box with half the page blank beside it. Then it
   was set in two columns to fill that space, which was worse: a note this
   short does not have the length to justify columns, so a single sentence
   broke across the gap and the reader had to jump back up to carry on.

   Newspaper columns need enough text that each one is a block worth
   reading. Three lines is not that. So: one column, full width, and the
   line length kept sane by the box's own padding rather than by a cap
   that leaves the page looking unfinished. */
.instore-privacy {
  margin: 0 0 56px; padding: 22px 26px; border-radius: 12px;
  background: var(--parchment-deep); color: var(--ink-soft);
  font-size: .97rem; line-height: 1.65;
  text-wrap: pretty;
}

.instore-visit {
  padding: 34px; border-radius: 16px; background: var(--parchment-deep);
}
.instore-visit h2 { margin: 0 0 8px; font-size: 1.9rem; }
/* No measure cap. At 60ch this broke a single sentence onto two lines
   with most of the panel empty beside it. */
.instore-visit > p { margin: 0 0 24px; color: var(--ink-soft); }
.instore-visit-facts {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 26px;
}
.instore-visit-facts h4 {
  margin: 0 0 6px; font-size: .74rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-soft);
}
.instore-visit-facts p { margin: 0; line-height: 1.6; }

@media (max-width: 980px) {
  /* Below this the two columns would both be too narrow to read, so the
     screen goes back above the prose. */
  .instore-lead { grid-template-columns: 1fr; gap: 34px; }
  .instore-lead-show { position: static; order: -1; }
  .instore-lead-text + .instore-lead-text { margin-top: 28px; }
  .instore-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .instore-visit-facts { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 620px) {
  .instore-grid { grid-template-columns: 1fr; }
  .instore-visit { padding: 24px; }
  .instore-visit-facts { grid-template-columns: 1fr; gap: 20px; }
  .kioskshow.is-live .kioskshow-frame { max-width: 270px; }
  .kioskshow-controls { margin-top: 124px; }
}

/* ---- What the swatch book is (/swatch-book/about/) ----------------------
   Three numbered steps, then four reassurances in a grid. The numbers are
   there because this genuinely is a sequence: press the plus, sort it out,
   bring it in. They are not decoration, and nothing else on the site is
   numbered for the sake of it. */
.sb-about-steps {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 30px;
}
.sb-about-step {
  background: var(--card); border-radius: 10px; padding: 30px 28px 32px;
  box-shadow: var(--shadow-soft);
}
.sb-about-num {
  font-family: var(--font-display); font-size: 2.4rem; line-height: 1;
  color: var(--accent); opacity: 0.32; margin-bottom: 10px;
}
.sb-about-step h2 { font-size: 1.2rem; margin-bottom: 10px; }
.sb-about-step p { color: var(--ink-soft); }

.sb-about-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 38px 48px;
}
.sb-about-grid h2 { font-size: 1.3rem; margin-bottom: 12px; }
.sb-about-grid p + p { margin-top: 12px; }
.sb-about-grid p { color: var(--ink-soft); }

.sb-about-samples {
  background: var(--card); border-radius: 10px; padding: 36px 36px 40px;
  box-shadow: var(--shadow-soft); max-width: 780px; margin: 0 auto;
  text-align: center;
}
.sb-about-samples h2 { margin-bottom: 14px; }
.sb-about-samples p { color: var(--ink-soft); max-width: 60ch; margin-left: auto; margin-right: auto; }

@media (max-width: 860px) {
  .sb-about-steps { grid-template-columns: 1fr; gap: 18px; }
  .sb-about-grid  { grid-template-columns: 1fr; gap: 30px; }
}
