/* Shared layout and responsive rules for the Oak & Chisel static site. */
html { scroll-behavior: smooth; }
img { max-width: 100%; }
/* ---- Layout system -------------------------------------------------------
   One gutter token drives every horizontal inset on the site. Sections are
   every section occupies the same box, so all edges land on one line. A
   section that paints a background insets only its own text (--band-pad). */
:root { --page-max: 1440px; --gutter: 80px; --band-y: 120px; --band-pad: 64px; --header-h: 96px; }

/* ---- Interactivity: hover/focus affordances, click-throughs, reveal-on-
   scroll ------------------------------------------------------------------
   Every transition here animates transform and/or opacity only (compositor-
   friendly, no layout shift), runs 150-400ms with a simple ease, and is
   fully disabled under prefers-reduced-motion below. Anything clickable is
   a real <a> or <button> — this file only styles states, it never invents
   affordances on non-interactive elements. */

/* Anchors that land under the sticky header keep their target clear of it. */
#services, #process, #contact, #interiors, #exteriors { scroll-margin-top: var(--header-h); }

.btn-motion { transition: transform 200ms ease; }
.btn-motion:hover, .btn-motion:focus-visible { transform: translateY(-2px); }

a.value-card { text-decoration: none; color: inherit; }
.value-card { transition: transform 200ms ease; }
.value-card:hover, .value-card:focus-within { transform: translateY(-4px); }

.card-link, .card-link-14, .project-card { transition: transform 200ms ease; }
.card-link:hover, .card-link:focus-within,
.card-link-14:hover, .card-link-14:focus-within,
.project-card:hover, .project-card:focus-within { transform: translateY(-3px); }

.media-box { overflow: hidden; }
.card-link picture, .card-link-14 picture, .project-card picture,
.card-link .media-box, .card-link-14 .media-box, .project-card .media-box { display: block; overflow: hidden; }
.media-box > picture { display: block; height: 100%; }
.card-link img, .card-link-14 img, .project-card img { transition: transform 300ms ease; }
.card-link:hover img, .card-link:focus-within img,
.card-link-14:hover img, .card-link-14:focus-within img,
.project-card:hover img, .project-card:focus-within img { transform: scale(1.06); }

/* Every content photo (.zoom on its <picture>) eases in slightly on hover,
   whether or not it's a link: the frame clips, only the image scales. */
.zoom { display: block; overflow: hidden; }
.zoom img { transition: transform 600ms cubic-bezier(0.2, 0.7, 0.2, 1); }
.zoom:hover img, a:hover .zoom img, a:focus-visible .zoom img { transform: scale(1.06); }

/* Process timeline: only steps with a real destination (an <a>, via
   .step-anchor.is-link) get the hover/focus affordance — a lifted number, an
   underline growing under the heading, and an arrow nudging into view. */
.step-li { position: relative; }
.step-anchor { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: 28px; }
a.step-anchor { text-decoration: none; color: inherit; }
.step-anchor.is-link { cursor: pointer; }
.step-anchor.is-link .step-num { transition: transform 200ms ease, background-color 200ms ease; }
.step-anchor.is-link:hover .step-num, .step-anchor.is-link:focus-visible .step-num { transform: translateY(-2px); background: #2F343B; }
.step-anchor .step-body h3 { position: relative; display: inline-block; }
.step-anchor.is-link .step-body h3::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -4px; height: 2px;
  background: #5F6B7A; transform: scaleX(0); transform-origin: left; transition: transform 220ms ease;
}
.step-anchor.is-link:hover .step-body h3::after, .step-anchor.is-link:focus-visible .step-body h3::after { transform: scaleX(1); }
.step-arrow { display: inline-block; margin-left: 8px; opacity: 0; transform: translateX(-4px); transition: opacity 200ms ease, transform 200ms ease; }
.step-anchor.is-link:hover .step-arrow, .step-anchor.is-link:focus-visible .step-arrow { opacity: 1; transform: translateX(0); }
.step-anchor.is-link:focus-visible { outline: 3px solid #8A94A3; outline-offset: 4px; }

/* Reveal-on-scroll: a one-time fade-and-rise. Staggered only within a group
   via --reveal-delay (set by site.js from each element's position among its
   siblings). Elements start visible if JS never runs (no-JS / IO missing). */
.reveal { display: block; opacity: 1; transform: none; }
.reveal.reveal-armed { opacity: 0; transform: translateY(18px); transition: opacity 420ms ease, transform 420ms ease; transition-delay: var(--reveal-delay, 0ms); }
.reveal.reveal-armed.is-visible { opacity: 1; transform: none; }

/* Hero entrance: plays once on load, not gated by scroll. */
.hero-in > * { opacity: 0; transform: translateY(14px); animation: hero-in 560ms ease forwards; }
.hero-in > *:nth-child(1) { animation-delay: 60ms; }
.hero-in > *:nth-child(2) { animation-delay: 150ms; }
.hero-in > *:nth-child(3) { animation-delay: 240ms; }
.hero-in > *:nth-child(4) { animation-delay: 330ms; }
.hero-in-img { opacity: 0; transform: translateY(14px); animation: hero-in 620ms ease forwards; animation-delay: 180ms; }
@keyframes hero-in { to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .btn-motion, .value-card, .card-link, .card-link-14, .project-card,
  .card-link img, .card-link-14 img, .project-card img,
  .step-anchor.is-link .step-num, .step-anchor.is-link .step-body h3::after, .step-arrow {
    transition: none !important;
  }
  .btn-motion:hover, .btn-motion:focus-visible,
  .value-card:hover, .value-card:focus-within,
  .card-link:hover, .card-link:focus-within,
  .card-link-14:hover, .card-link-14:focus-within,
  .project-card:hover, .project-card:focus-within,
  .card-link:hover img, .card-link:focus-within img,
  .card-link-14:hover img, .card-link-14:focus-within img,
  .project-card:hover img, .project-card:focus-within img,
  .zoom:hover img, a:hover .zoom img, a:focus-visible .zoom img,
  .step-anchor.is-link:hover .step-num, .step-anchor.is-link:focus-visible .step-num {
    transform: none !important;
  }
  .reveal.reveal-armed { opacity: 1 !important; transform: none !important; transition: none !important; }
  .hero-in > *, .hero-in-img { opacity: 1 !important; transform: none !important; animation: none !important; }
}

.page { box-sizing: border-box; width: 100%; max-width: var(--page-max); margin: 0 auto; padding: 0 var(--gutter); display: flex; flex-direction: column; min-height: 100vh; }
/* Vertical padding belongs to the footer's own class (.site-footer, 56px) or
   to its inline style (index, 64px). Setting it here too would outrank
   .site-footer on specificity and silently override it. */
.page > footer { margin-top: auto; }

/* A section that paints a background occupies the SAME box as every other
   section, so its edges land on the one alignment line. Its own text is
   inset by --band-pad so it does not touch the coloured edge — the same
   relationship a card has with its interior. */
.painted { padding-left: var(--band-pad); padding-right: var(--band-pad); }

.band { padding-top: var(--band-y); padding-bottom: var(--band-y); }
.band--accent { background: #5F6B7A; color: #FAF9F6; }
.card { background: #FFFFFF; }
/* Card interiors. These used to be targeted by [style*="padding: 64px;"],
   which silently stopped matching the moment the inline value changed. */
.card-body { padding: 64px; }
.card-body--tall { padding: 104px 64px; }

/* ---- Components and type ---------------------------------------------------
   Extracted verbatim from repeated inline styles, so computed values are
   unchanged. Each class carries every declaration its inline original did. */
.t-body      { font-size: 16px; line-height: 1.55; color: #5E646C; }
.t-serif-22  { font-family: Marcellus, Georgia, serif; font-size: 22px; }
.t-26        { font-size: 26px; }
.t-30        { font-size: 30px; }
.t-17        { font-size: 17px; line-height: 1.7; color: #4E545C; }
.t-meta      { font-size: 16px; color: #5F6B7A; font-weight: 500; }
.t-strong    { font-weight: 600; }
.t-muted     { color: #5E646C; }
.t-step      { font-size: 17px; line-height: 1.6; color: #4E545C; max-width: 620px; }

.stack-6     { display: flex; flex-direction: column; gap: 6px; }
.field       { display: flex; flex-direction: column; gap: 6px; font-size: 15px; font-weight: 600; }
.spec-row    { display: flex; flex-direction: column; gap: 4px; padding: 20px 0; border-bottom: 1px solid #E4E6E9; }
.rule-top    { display: flex; flex-direction: column; gap: 4px; border-top: 1px solid #B4BCC7; padding-top: 12px; }
.bullets     { margin: 0; padding-left: 18px; font-size: 16px; line-height: 1.9; color: #2F343B; }
.card-link   { display: flex; flex-direction: column; gap: 16px; text-decoration: none; color: #2F343B; }

/* Recent projects: one tall image on the left, two stacked cards on the right.
   The grid makes both COLUMNS equal height, but the right column's content was
   shorter than the left's, so its last caption floated ~33px above the left
   one's. Letting the two cards share the column height and the images absorb
   the remainder makes the bottoms line up regardless of how captions wrap. */
.proj-side > .card-link-14 { flex: 1; min-height: 0; }
.proj-side > .card-link-14 > img { flex: 1; min-height: 0; object-fit: cover; }

.img-cover   { display: block; width: 100%; height: 100%; object-fit: cover; object-position: center center; }
.img-tag     { position: absolute; top: 16px; left: 16px; font-size: 13px; font-weight: 600; color: #FAF9F6; background: #2F343B; padding: 5px 10px; }

/* Numbered process timeline. The circles hang half over the ol's left border. */
.step-li     { padding: 0 0 40px 0; margin-left: -32px; }
.step-num    { width: 64px; height: 64px; border-radius: 50%; background: #5F6B7A; color: #FAF9F6; display: flex; align-items: center; justify-content: center; font-family: Marcellus, Georgia, serif; font-size: 24px; }
.step-body   { display: flex; flex-direction: column; gap: 8px; padding-top: 6px; }

/* ---- Extracted from remaining repeated inline styles ---------------------
   Same declarations, same computed values; verified against a geometry baseline. */
.card-link-14 { display: flex; flex-direction: column; gap: 14px; text-decoration: none; color: #2F343B; }
.card-split { display: grid; grid-template-columns: 160px minmax(0, 1fr); background: #FFFFFF; }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; }
.quote-card { margin: 0; display: flex; flex-direction: column; justify-content: space-between; gap: 32px; padding: 40px; border: 1px solid #5A6472; min-height: 320px; box-sizing: border-box; }
.row-baseline { display: flex; justify-content: space-between; align-items: baseline; }
.rule-top-2 { display: flex; flex-direction: column; gap: 14px; padding-top: 8px; border-top: 2px solid #8A94A3; }
.site-footer { margin-top: auto; background: #2F343B; color: #C8CDD4; padding: 56px var(--band-pad); display: flex; justify-content: space-between; font-size: 15px; }
.stack { display: flex; flex-direction: column; }
.stack-20 { display: flex; flex-direction: column; gap: 20px; }
.stack-24 { display: flex; flex-direction: column; gap: 24px; }
.stack-32 { display: flex; flex-direction: column; gap: 32px; }
.stack-4-16 { display: flex; flex-direction: column; gap: 4px; font-size: 16px; }
.stack-40 { display: flex; flex-direction: column; gap: 40px; }
.t-15-accent { font-size: 15px; color: #5F6B7A; }
.t-17-tight { font-size: 17px; line-height: 1.6; color: #4E545C; }
.t-20 { font-size: 20px; line-height: 1.6; color: #4E545C; }
.t-20-narrow { font-size: 20px; line-height: 1.6; color: #4E545C; max-width: 720px; }
.t-24 { font-size: 24px; }
.t-28-top { font-size: 28px; padding-top: 16px; }
.t-52 { font-size: 52px; }
.t-light { color: #FAF9F6; }
.t-quote-mark { font-family: Marcellus, Georgia, serif; font-size: 72px; line-height: 0.6; color: #B4BCC7; }
.t-serif-23 { margin: 0; font-family: Marcellus, Georgia, serif; font-size: 23px; line-height: 1.45; }
.t-serif-26-light { font-family: Marcellus, Georgia, serif; font-size: 26px; color: #FAF9F6; letter-spacing: 0.06em; }
.tile { background: #EDEEF0; padding: 48px; display: flex; flex-direction: column; gap: 14px; }
.value-card { display: flex; flex-direction: column; gap: 24px; background: #FFFFFF; border-top: 4px solid #8A94A3; padding: 40px; }


.site-header { position: sticky; top: 0; z-index: 20; display: flex; align-items: center; justify-content: space-between; gap: 24px; min-height: 96px; padding: 0; background: #FAF9F6; border-bottom: 1px solid #E4E6E9; }
.brand img { display: block; height: 68px; width: auto; }
.site-nav { display: flex; align-items: center; gap: 36px; font-size: 16px; font-weight: 500; }
.site-nav a { color: #2F343B; text-decoration: none; }
.site-nav a:hover, .site-nav a[aria-current="page"] { color: #5F6B7A; text-decoration: underline; text-underline-offset: 6px; }
.site-nav .nav-cta { padding: 14px 24px; background: #5F6B7A; color: #FFFFFF; border-radius: 2px; }
.site-nav .nav-cta:hover { background: #2F343B; color: #FFFFFF; text-decoration: none; }
.menu-toggle { display: none; min-height: 44px; padding: 0 16px; background: transparent; border: 1px solid #2F343B; color: #2F343B; font: inherit; font-weight: 600; border-radius: 2px; cursor: pointer; }

.project-card[hidden] { display: none !important; }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 3px solid #8A94A3; outline-offset: 1px; }
#contact-form input[aria-invalid="true"], #contact-form textarea[aria-invalid="true"] { border-color: #A33B2F !important; }

/* Floating quote chat */
.qc-launcher { position: fixed; right: 24px; bottom: 24px; z-index: 40; display: flex; align-items: center; gap: 12px; height: 60px; padding: 0 24px 0 18px; background: #2F343B; color: #FAF9F6; border: 0; font: inherit; font-weight: 600; font-size: 17px; border-radius: 30px; box-shadow: 0 8px 24px rgba(47, 52, 59, 0.25); cursor: pointer; }
.qc-launcher[hidden] { display: none; }
.qc-panel { position: fixed; right: 24px; bottom: 24px; z-index: 41; width: 400px; max-width: calc(100vw - 32px); height: 640px; max-height: calc(100vh - 48px); display: flex; flex-direction: column; background: #FFFFFF; border: 1px solid #DDE0E4; box-shadow: 0 16px 48px rgba(47, 52, 59, 0.25); font-family: Karla, "Helvetica Neue", sans-serif; }
.qc-panel[hidden] { display: none; }
/* The same chat, mounted inline in the contact section rather than floating.
   Shares every .qc-* rule; only the framing differs — it sits in the layout,
   so no fixed positioning, no shadow, and no close button. */
.qc-inline { display: flex; flex-direction: column; min-height: 520px; background: #FFFFFF; border: 1px solid #DDE0E4; font-family: Karla, "Helvetica Neue", sans-serif; color: #2F343B; }
.qc-inline .qc-log { min-height: 280px; }
.qc-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px 14px 20px; background: #2F343B; color: #FAF9F6; }
.qc-title { font-family: Marcellus, Georgia, serif; font-size: 20px; }
.qc-sub { font-size: 13px; color: #B4BCC7; }
.qc-close { width: 44px; height: 44px; background: none; border: 0; color: #FAF9F6; font-size: 26px; line-height: 1; cursor: pointer; }
.qc-log { flex: 1; overflow-y: auto; padding: 20px; display: flex; flex-direction: column; gap: 12px; background: #FAF9F6; }
.qc-msg { max-width: 82%; margin: 0; padding: 12px 14px; font-size: 15px; line-height: 1.5; }
.qc-bot { align-self: flex-start; background: #EDEEF0; color: #2F343B; border-radius: 2px 14px 14px 14px; }
.qc-user { align-self: flex-end; background: #5F6B7A; color: #FFFFFF; border-radius: 14px 2px 14px 14px; }
.qc-msg ul, .qc-msg ol { margin: 6px 0 0; padding-left: 22px; }
.qc-msg li { margin: 3px 0; }
.qc-msg code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }
.qc-foot { padding: 16px 20px 20px; border-top: 1px solid #E4E6E9; display: flex; flex-direction: column; gap: 12px; }
/* FIXED height, not min-height: every question presents in the same frame, so
   the panel never resizes as the control swaps between choice buttons and a
   text field. Sized to the tallest step (four wrapping options); anything
   taller scrolls rather than pushing the layout around. */
.qc-controls { min-height: 60px; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; justify-content: flex-start; }
.qc-typing { display: inline-flex; align-items: center; gap: 5px; padding: 14px; }
.qc-dot { width: 7px; height: 7px; border-radius: 50%; background: #8A929C; animation: qc-blink 1.4s infinite both; }
.qc-dot:nth-child(2) { animation-delay: 0.2s; }
.qc-dot:nth-child(3) { animation-delay: 0.4s; }
@keyframes qc-blink { 0%, 80%, 100% { opacity: 0.25; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-3px); } }
/* Motion here is decoration, not information: the dots still read as waiting. */
@media (prefers-reduced-motion: reduce) { .qc-dot { animation: none; opacity: 0.45; } }
.qc-input:disabled { background: #F4F5F6; }
.qc-send:disabled { opacity: 0.45; cursor: default; }
.qc-busy { margin: 0; align-self: center; padding-top: 14px; font-size: 15px; color: #5E646C; }
.qc-restart { width: 100%; }
.qc-options { display: flex; flex-wrap: wrap; gap: 8px; }
.qc-option { min-height: 44px; padding: 0 16px; border: 1px solid #5F6B7A; background: #FFFFFF; color: #5F6B7A; font: inherit; font-style: normal; font-weight: 600; font-size: 15px; border-radius: 22px; cursor: pointer; }
.qc-option:hover { background: #5F6B7A; color: #FFFFFF; }
.qc-panel button:focus-visible, .qc-inline button:focus-visible { outline: 3px solid #8A94A3; outline-offset: 1px; }
/* Slot-time choices: same pill as the opening chips, grouped under a day
   label when a reply covers more than one day. */
.qc-choices { width: 100%; }
.qc-choice-day { flex-basis: 100%; margin: 4px 0 -2px; font-family: Marcellus, Georgia, serif; font-style: normal; font-size: 13px; color: #5E646C; }
.qc-option-alt { border-color: #BCC2CA; color: #5E646C; }
.qc-option-alt:hover { background: #5E646C; border-color: #5E646C; color: #FFFFFF; }
.qc-row { display: flex; gap: 8px; }
.qc-input { flex: 1; min-width: 0; height: 48px; padding: 0 14px; border: 1px solid #BCC2CA; font: inherit; font-size: 16px; border-radius: 2px; }
.qc-send, .qc-restart { height: 48px; padding: 0 18px; background: #5F6B7A; color: #FFFFFF; border: 0; font: inherit; font-weight: 600; font-size: 16px; border-radius: 2px; cursor: pointer; }
.qc-restart { background: #2F343B; }
.qc-skip { align-self: flex-start; min-height: 44px; padding: 0; background: none; border: 0; color: #5F6B7A; font: inherit; font-weight: 600; font-size: 15px; text-decoration: underline; cursor: pointer; }
.qc-note { margin: 0; font-size: 12px; line-height: 1.5; color: #5E646C; }
/* Honeypot: invisible to humans, irresistible to form-filling bots. Hidden
   with position/opacity rather than display:none, which some bots skip. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; opacity: 0; pointer-events: none; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

@media (max-width: 1100px) {
  /* The gutter token does all the work — no per-section overrides needed. */
  :root { --gutter: 32px; --band-y: 88px; --band-pad: 32px; }
  .site-nav { gap: 22px; }
}

@media (max-width: 860px) {
  :root { --gutter: 20px; --band-y: 56px; --band-pad: 20px; --header-h: 76px; }
  .site-header { min-height: 76px; flex-wrap: wrap; }
  .brand img { height: 50px; }
  .menu-toggle { display: block; }
  .site-nav { display: none; width: 100%; flex-direction: column; align-items: stretch; gap: 0; padding-bottom: 16px; }
  .site-nav.open { display: flex; }
  .site-nav a { padding: 12px 0; }
  .site-nav .nav-cta { margin-top: 8px; text-align: center; }
  .rgrid { grid-template-columns: minmax(0, 1fr) !important; gap: 32px !important; }
  .rgrid > div:has(> .vlabel) { display: none !important; }
  .card-body, .card-body--tall { padding: 32px 20px; }
  .pad-48, .form-panel { padding: 28px 20px !important; }
  .page footer { flex-direction: column; gap: 24px !important; }
  .page section > .row-split { flex-direction: column; align-items: flex-start !important; gap: 16px !important; }
  h1 { font-size: 42px !important; }
  h2 { font-size: 32px !important; }
  h3 { font-size: 24px !important; }
  .media-tall { height: 340px !important; }
  .media-mid { height: 280px !important; }
  .media-box { height: 360px !important; }
  .deco { display: none; }
  .frame { padding: 0 !important; }
  .steps > li { margin-left: 0 !important; }
  .steps > li > .step-anchor { grid-template-columns: 48px minmax(0, 1fr) !important; gap: 16px !important; }
  .steps > li .step-num { width: 48px !important; height: 48px !important; font-size: 20px !important; }
  .steps { border-left: 0 !important; }
  .page ul.rgrid { column-gap: 0 !important; gap: 0 !important; }
  .qc-launcher { right: 16px; bottom: 16px; }
  .qc-panel { right: 0; bottom: 0; width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; }
}

/* Hero: full-bleed facade photo, copy below. Photo is cropped to 16:9 on
   desktop (sign sits mid-frame) and swaps to a square sign-centred crop on phones. */
.hero-facade { display: flex; flex-direction: column; gap: 56px; padding: 32px 0 112px; }
.hero-photo picture, .hero-photo img { display: block; width: 100%; height: auto; }
.hero-photo img { aspect-ratio: 16 / 9; object-fit: cover; object-position: 50% 50%; background: #2F343B; }
.hero-copy { max-width: 760px; }
@media (max-width: 700px) {
  .hero-facade { gap: 32px; padding: 16px 0 72px; }
  .hero-photo img { aspect-ratio: 1 / 1; }
}

@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* ---- Before/after comparison ------------------------------------------------
   One frame, two photos: the "after" photo fills it, the "before" photo sits on
   top clipped to the left of the divider (--pos). Dragging or swiping the line
   left reveals more of the finished work; right reveals more of the original.
   A native range input covers the frame, so keyboard arrows, screen readers
   and touch all work; touch-action keeps vertical page scrolling. */
.ba { margin: 0; display: flex; flex-direction: column; gap: 14px; width: 100%; max-width: 880px; }
.ba-frame { position: relative; overflow: hidden; height: 560px; background: #DDE1E6; user-select: none; -webkit-user-select: none; }
.ba-frame picture, .ba-frame img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.ba-frame img { object-fit: cover; }
.ba-before { clip-path: inset(0 calc(100% - var(--pos)) 0 0); }
.ba-line { position: absolute; top: 0; bottom: 0; left: var(--pos); width: 2px; margin-left: -1px; background: #FFFFFF; box-shadow: 0 0 0 1px rgba(47, 52, 59, 0.25); pointer-events: none; }
.ba-knob { position: absolute; top: 50%; left: 50%; width: 44px; height: 44px; margin: -22px 0 0 -22px; border-radius: 50%; background: #FFFFFF; color: #2F343B; display: flex; align-items: center; justify-content: center; box-shadow: 0 6px 18px rgba(47, 52, 59, 0.28); transition: transform 200ms ease; }
.ba-frame:hover .ba-knob, .ba-frame[data-kb] .ba-range:focus ~ .ba-line .ba-knob { transform: scale(1.08); }
.ba-tag { position: absolute; top: 16px; padding: 6px 12px; font-size: 14px; font-weight: 600; letter-spacing: 0.02em; color: #FFFFFF; background: rgba(47, 52, 59, 0.72); border-radius: 2px; pointer-events: none; }
.ba-tag { transition: opacity 120ms linear; }
/* Each label fades out as the line sweeps over its side: "Before" as the
   line nears the left edge, "After" as it nears the right (--p is 0..1). */
.ba-tag-before { left: 16px; opacity: clamp(0, calc((var(--p, 0.5) - 0.08) / 0.17), 1); }
.ba-tag-after { right: 16px; opacity: clamp(0, calc((0.92 - var(--p, 0.5)) / 0.17), 1); }
.ba-range { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; pointer-events: none; -webkit-appearance: none; appearance: none; }
.ba-frame { cursor: ew-resize; touch-action: pan-y; }
.ba-frame[data-kb]:has(.ba-range:focus) { outline: 3px solid #8A94A3; outline-offset: 4px; }
.ba-caption { font-size: 15px; color: #5E646C; }
@media (max-width: 760px) { .ba-frame { height: 380px; } }

/* Portfolio cards that hold a before/after slider (cards are not links, so dragging works). */
.project-card .ba { max-width: none; height: 100%; gap: 0; }
.project-card .ba-frame { height: 100%; }
.project-card .ba-frame img, .project-card:hover .ba-frame img, .project-card:focus-within .ba-frame img { transform: none; }
.project-card .ba-tag { top: 56px; }
.project-card .img-tag { z-index: 2; pointer-events: none; }
