@font-face { font-family: "STIX Two Text"; src: url("/static/fonts/stixtwotext-400.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "STIX Two Text"; src: url("/static/fonts/stixtwotext-600.woff2") format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "STIX Two Text"; src: url("/static/fonts/stixtwotext-400i.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "Hanken Grotesk"; src: url("/static/fonts/hankengrotesk-400.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Hanken Grotesk"; src: url("/static/fonts/hankengrotesk-500.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
/* `body.sda`, not `body`. This stylesheet is also pulled into the internal
   form editor (templates/admin_form_editor.html) so its disabled preview can
   render real public components; while the public ground was cream that was
   invisible, and the moment it went night a bare `body` rule would have taken
   the whole internal page dark with it. catalog_base.html is the only template
   that puts `sda` on the body. Same reason for the :has() on <html>. */
html:has(> body.sda) { background: var(--sda-paper); }  /* iOS overscroll, not white */
body.sda {
  margin: 0; background: var(--sda-paper); color: var(--sda-ink);
  /* Checkboxes, radios, select popups and scrollbars are painted by the
     platform, not by this sheet. Without this they arrive white on a night
     page: the hello form is fifteen white squares in a column. */
  color-scheme: dark;
}
/* Type-level selector, and it must STAY type-level. At (0,0,1) it loses to
   every button and link class; written as `.something a` it would be (0,1,1)
   and would take the label colour off .sda-btn--primary. That failure shipped
   once in the night concept and is now pinned by a test. */
a { color: inherit; }
.sda-skip { position: absolute; left: -9999px; }
.sda-skip:focus { position: fixed; top: .5rem; left: .5rem; z-index: 100; background: var(--sda-night); color: var(--sda-night-ink); padding: .6rem 1rem; outline: var(--sda-focus); }
.sda-mark-frame { display: block; line-height: 0; flex: 0 0 auto; }
.sda-shell { min-height: 100vh; display: flex; flex-direction: column; }
.sda-container { width: min(100% - 2rem, 1200px); margin-inline: auto; }
.sda-section { padding-block: var(--sda-space-band); }
.sda-section--lg { padding-block: var(--sda-space-band-lg); }
/* The strip above the header used to be an inverted cream-on-ink bar, which on
   a night page is a bright band across the top of every screen: the first thing
   the eye lands on would be an announcement rather than a photograph. It goes
   espresso with a copper label, which is the concept's treatment. */
.sda-announcement { padding: .55rem 1rem; text-align: center; color: var(--sda-copper); background: var(--sda-night); border-bottom: var(--sda-rule-warm); font: 500 var(--sda-label)/1.3 var(--sda-sans); letter-spacing: var(--sda-ls-label); text-transform: uppercase; }
.sda-header { background: color-mix(in srgb, var(--sda-night) 88%, transparent); backdrop-filter: blur(6px); border-bottom: var(--sda-rule); position: sticky; top: 0; z-index: 20; }
.sda-header__inner { min-height: 92px; display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.sda-brand { display: inline-flex; align-items: center; gap: .7rem; text-decoration: none; }
.sda-mark { width: var(--sda-mark-nav); height: var(--sda-mark-nav); flex: 0 0 auto; display: block; background: currentColor; mask: url("/static/sda/sda-mark.svg") center / contain no-repeat; -webkit-mask: url("/static/sda/sda-mark.svg") center / contain no-repeat; }
.sda-brand__name { display: block; font: 500 .9rem/1.1 var(--sda-sans); letter-spacing: .13em; }
.sda-brand__sub { display: block; margin-top: .2rem; font: italic var(--sda-caption)/1.1 var(--sda-serif); color: var(--sda-ink-faint); }
.sda-nav { display: flex; align-items: center; gap: clamp(.75rem, 2vw, 1.7rem); font: 500 .82rem/1.2 var(--sda-sans); }
/* `:not(.sda-btn)` is what keeps this off the Inquire button. It sets colour as
   well as decoration now, so the qualifier is load-bearing, not tidiness. */
.sda-nav > a:not(.sda-btn) { text-decoration: none; color: var(--sda-ink-soft); }
.sda-nav > a:not(.sda-btn):hover { color: var(--sda-ink); }
.sda-mobile { display: none; }
/* The padding is the point. This control only ever appears under 850px, which
   means it is only ever tapped, and at line-height 1 the word "Menu" gave a
   target 13px tall: the whole navigation of the public site, on the phone that
   just scanned a label. The negative margin keeps the header looking as it did
   while the thumb gets 44px. */
.sda-mobile summary { list-style: none; cursor: pointer; font: 500 .82rem/1 var(--sda-sans); letter-spacing: .1em; text-transform: uppercase; display: inline-flex; align-items: center; min-height: 44px; padding: 0 .5rem; margin: 0 -.5rem; }
.sda-mobile summary::-webkit-details-marker { display: none; }
/* Menu / Close, and a caret that turns over with it. Both are pure CSS off the
   `open` attribute so the state is readable with scripting off. */
.sda-mobile__label { display: inline-flex; align-items: center; gap: .5rem; }
.sda-mobile__label::after { content: ""; width: 8px; height: 8px; margin-top: -3px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); transition: transform var(--sda-t-press) ease-out; }
.sda-mobile[open] .sda-mobile__label::after { margin-top: 3px; transform: rotate(-135deg); }
.sda-mobile [data-menu-close] { display: none; }
.sda-mobile[open] [data-menu-open] { display: none; }
.sda-mobile[open] [data-menu-close] { display: inline; }
/* The panel drops BELOW the header instead of over it.
   It used to be `position: fixed; inset: 0`, a full-screen sheet laid on top
   of the one control that dismisses it. The z-index: 30 could never have
   saved it: the panel lives inside `.sda-header`, and that header is its own
   stacking context (sticky with a z-index, and a backdrop-filter besides), so
   30 only ever meant "30 within the header" and document order decided the
   rest. With no close button in the markup, no Escape handler and no dismissal
   on an outside tap, the only way out of the navigation was the back button.
   That is the "spills into everything else" a peer reported.
   `top: 100%` resolves against the header, so the summary stays visible and
   tappable underneath the caret, which is what lets it be the close control. */
.sda-mobile__panel {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 30;
  padding: .6rem clamp(1rem, 4vw, 1.6rem) 1.6rem;
  background: var(--sda-night); border-bottom: var(--sda-rule);
  box-shadow: 0 26px 44px -26px rgba(0, 0, 0, .9);
  display: flex; flex-direction: column;
  max-height: 74dvh; overflow-y: auto; overscroll-behavior: contain;
}
/* Deliberately sets no colour. `.sda-mobile__panel a` is (0,2,1) and would bury
   the Inquire button's own label colour; the panel inherits cream from the
   shell and the button keeps its variant. */
.sda-mobile__panel a { font: 600 var(--sda-h3)/1.2 var(--sda-serif); text-decoration: none; }
/* A row, not a word: these are thumb targets on the one page a customer opens
   after scanning a label at the booth. */
.sda-mobile__panel a:not(.sda-btn) { display: flex; align-items: center; min-height: 52px; border-bottom: var(--sda-rule); }
.sda-mobile__panel .sda-btn { align-self: stretch; margin-top: 1.2rem; font: 500 .9rem/1 var(--sda-sans); }
.sda-flash { margin-top: 1rem; padding: .8rem 1rem; border: var(--sda-rule); border-left: 2px solid var(--sda-verdigris); background: var(--sda-panel); font: var(--sda-small)/1.4 var(--sda-serif); }
.sda-main { flex: 1; }
/* ---------- Grounds: the sepia zones and their seams ----------
   The sepia round, 2026-08-05 (Les, via Logan). Two rules live here.

   1. The zones that HOST the work get the deepest ground on the site. A piece
      photographed on a light bench is the brightest object in its own band and
      comes forward; the bands around it sit lighter, which is what makes that
      true rather than an assertion. `--sda-stage` is not black on purpose:
      "black is excessive", and a black band behind a photograph reads as a
      hole rather than as a room.

   2. The rest of the page alternates warm and cool sepia so a scroll has a
      temperature to it. The difference is chroma, not hue; see tokens.css.

   The seams are the part that is easy to get wrong. Bands used to meet at a
   hard edge, which on a page of near-blacks reads as a seam in the screen. Two
   pseudo-elements fade the page ground back in over `--sda-seam` at the top
   and bottom of every zone, so ANY two neighbours dissolve through the same
   common ground and no zone has to know what it sits next to.

   The z-index: -1 is load-bearing and so is the isolation. CSS paints, in this
   order, a stacking context's own background, THEN its negative z-index
   descendants, THEN in-flow content. Without `isolation` the zone is not a
   stacking context and the pseudo would fall behind the zone's own background
   colour and vanish; at z-index 0 it would paint over the text instead. This
   is the same mechanism the hero has used since the night pass.

   Ground-to-ground gradients are permitted (Logan, 2026-08-05, extending the
   legend's gradient ban). Component FILLS are still flat: no gradient buttons,
   cards or chips. */
.sda-zone { position: relative; isolation: isolate;
  background-color: var(--sda-zone-ground, var(--sda-paper)); }
.sda-zone--warm { --sda-zone-ground: var(--sda-band-warm); }
.sda-zone--cool { --sda-zone-ground: var(--sda-band-cool); }
.sda-zone--stage { --sda-zone-ground: var(--sda-stage); }
.sda-zone::before, .sda-zone::after { content: ""; position: absolute; left: 0; right: 0;
  height: var(--sda-seam); z-index: -1; pointer-events: none; }
.sda-zone::before { top: 0; background: linear-gradient(180deg, var(--sda-paper), transparent); }
.sda-zone::after { bottom: 0; background: linear-gradient(0deg, var(--sda-paper), transparent); }
/* ---------- The vignette device ----------
   A sepia photograph used as a GROUND, under a scrim that is heavy at the
   edges and over the type and eases toward the middle. This is exactly what
   the hero has always done with its scrim; Les asked for that treatment to
   become a device other zones can take, so it is a class rather than one
   band's hand-tuned gradient.

   The photograph is baked sepia in the FILE (scripts/build_sepia_editorial.py),
   never `filter: sepia()`. Three reasons: the filter is a different matrix in
   every engine, it costs a compositor paint on a full-bleed band that scrolls,
   and a test can open a JPEG but cannot read a filter's output.

   The scrim stays in CSS because it is the part that adapts: a band whose copy
   sits left takes the side-wash below, a band whose copy runs the full width
   takes `--hold`, and the alpha floor in both is set so the soft ink clears
   4.5:1 over a worst-case light photograph. The arithmetic is in tokens.css.

   The band's own top and bottom fade to the page ground the way a `.sda-zone`
   seam does, which is why a photographic band does not also need the zone
   pseudo-elements: it carries its seam as the first scrim layer. */
.sda-vignette { position: relative; isolation: isolate; overflow: hidden;
  background-color: var(--sda-stage); }
.sda-vignette__bg { position: absolute; inset: 0; z-index: -2; }
.sda-vignette__bg img { width: 100%; height: 100%; object-fit: cover; }
.sda-vignette__scrim { position: absolute; inset: 0; z-index: -1; background:
  linear-gradient(180deg,
    var(--sda-paper) 0%,
    var(--sda-vignette-none) var(--sda-seam),
    var(--sda-vignette-none) calc(100% - var(--sda-seam)),
    var(--sda-paper) 100%),
  linear-gradient(96deg,
    var(--sda-scrim-text) 0%,
    var(--sda-scrim-text) 32%,
    var(--sda-scrim-hold) 56%,
    var(--sda-vignette-none) 100%),
  radial-gradient(120% 106% at 70% 44%,
    var(--sda-vignette-core) 0%,
    var(--sda-vignette-mid) 56%,
    var(--sda-vignette-edge) 100%); }
/* Copy that runs the full width of the band: the directional layer stops being
   a side-wash and becomes a floor, or the step columns on the right sit on
   bare photograph. */
.sda-vignette--hold .sda-vignette__scrim { background:
  linear-gradient(180deg,
    var(--sda-paper) 0%,
    var(--sda-vignette-none) var(--sda-seam),
    var(--sda-vignette-none) calc(100% - var(--sda-seam)),
    var(--sda-paper) 100%),
  linear-gradient(180deg,
    var(--sda-scrim-text) 0%,
    var(--sda-scrim-hold) 46%,
    var(--sda-scrim-text) 100%),
  radial-gradient(128% 112% at 50% 44%,
    var(--sda-vignette-core) 0%,
    var(--sda-vignette-mid) 58%,
    var(--sda-vignette-edge) 100%); }
/* Focal points, one per photograph, in CSS rather than on the element: the
   crop a `cover` slot takes is a property of the picture and the shape of the
   slot, not of the page that happens to use it, and an inline style is one
   more thing a content-security policy has to allow.
   Provenance: the curb haul is a near-square shot in a wide band, so almost
   all of it overflows vertically; 62% keeps the pile of rough and the person
   bagging it in the band instead of centring on empty sidewalk.
   Steps: the bench is at the lower left of a 4:3 frame; 38% holds the wheel
   and the hands in the band under the step columns. */
.sda-vignette--provenance .sda-vignette__bg img { object-position: 50% 62%; }
.sda-vignette--steps .sda-vignette__bg img { object-position: 46% 38%; }
/* ---------- The makers, story page (2026-08-07) ----------
   Two people, side by side, equal width, because the studio's whole claim is
   that it is two trades and neither is the assistant. A single column at the
   narrow breakpoint stacks them in page order rather than reflowing, so the
   pairing survives as a sequence.

   No panel and no card. The house rule is that text is never boxed: the frame
   belongs to the photograph and whitespace does the rest. The rule above the
   heading is the same hairline the rest of this page uses to separate sections
   of prose. */
.sda-makers { margin-top: clamp(3rem, 7vw, 5rem); padding-top: clamp(2rem, 4vw, 3rem); border-top: var(--sda-rule); }
.sda-makers__pair { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(1.6rem, 4vw, 3rem); margin-top: 1.8rem; }
@media (max-width: 720px) { .sda-makers__pair { grid-template-columns: 1fr; } }
/* The mount is NOT `.sda-frame`. That class is the 4:5 product frame, it is
   barred from this page (S52), and S50 guarantees no sepia asset ever sits
   inside one. This is the archive band's construction instead: a fixed box on
   the deep ground, the photograph CONTAINED so nothing is cropped, and the
   copper hairline doing the separating in place of a mat shadow. 4:3 because
   both portraits were cut to it, so the pair sits level whatever the sources
   were shot at. */
.sda-maker__mount { display: block; aspect-ratio: 4 / 3; overflow: hidden;
  background: var(--sda-stage); border: var(--sda-rule-warm); }
.sda-maker__mount picture { display: contents; }
.sda-maker__mount img { width: 100%; height: 100%; object-fit: contain; display: block; }
.sda-maker h3 { margin: 1.1rem 0 .4rem; font: 400 1.15rem/1.3 var(--sda-serif); }
.sda-maker p { margin: 0; max-width: 46ch; }
/* Showroom: the cases and the painting sit across the MIDDLE of a 4:3 frame,
   with ceiling above and a bench corner and an armchair below, so a centred
   crop on a wide band would hold the ceiling tiles. 52% keeps the shelves of
   finished work in the strip the copy sits over. */
.sda-vignette--showroom .sda-vignette__bg img { object-position: 50% 52%; }
/* ---------- Hero: the company, not a piece ----------
   The night register's fold. An establishing bench photograph is bled behind
   the copy under a warm scrim, so the light in the hero comes from a
   photograph rather than from a painted panel; the company sentence runs at
   display size; a copper claim bar closes the block. The featured piece used
   to own 540px of the fold and now owns 330: it is the small matted print at
   the right, not the subject. `.sda-hero` is the positioning context, and
   `.sda-hero__inner` is the grid that used to live on `.sda-hero` itself. */
.sda-hero { position: relative; isolation: isolate; overflow: hidden; background: var(--sda-night); }
.sda-hero__bg { position: absolute; inset: 0; z-index: -2; }
/* The focal point is picked for the photograph in the slot, and the slot has
   now changed twice. It held the flat-lap close-up at 46%, then the wide wheel
   shot at 72% 38% where the y kept a head clear of the header rule, and from
   2026-08-07 it holds the tool bench, which has no head in it at all.

   A near-square photograph in a wide box overflows by more than half its
   height, so a few points of y move the frame a long way. 56% puts the bench
   surface across the band, the lamp arm entering from the top left, and drops
   the empty foreground the bottom of the frame is made of. The x goes back to
   centre: the wheel shot needed 72% to hold a person standing off to one side,
   and this picture is spread evenly across its whole width. */
.sda-hero__bg img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 56%; }
/* The scrim mixes toward --sda-vignette, not --sda-night. It was night, which
   worked only while night WAS the deepest thing on the site; the sepia retune
   lifted the whole ground family and a scrim built out of a page-level ground
   stopped holding its copy (the copper claim bar measured 4.29:1 against the
   shipped pixels). The scrim colour is the scrim colour: one step under
   --sda-stage, shared with the vignette device and with the photographs' own
   black point. The last stop still mixes toward --sda-paper, because that stop
   is the hand-back to the page rather than a scrim. */
.sda-hero__scrim { position: absolute; inset: 0; z-index: -1; background:
  linear-gradient(180deg,
    color-mix(in srgb, var(--sda-vignette) 55%, transparent) 0%,
    color-mix(in srgb, var(--sda-vignette) 0%, transparent) 26%,
    color-mix(in srgb, var(--sda-vignette) 0%, transparent) 62%,
    color-mix(in srgb, var(--sda-vignette) 92%, transparent) 100%),
  linear-gradient(96deg,
    color-mix(in srgb, var(--sda-vignette) 96%, transparent) 0%,
    color-mix(in srgb, var(--sda-vignette) 90%, transparent) 34%,
    color-mix(in srgb, var(--sda-vignette) 50%, transparent) 62%,
    color-mix(in srgb, var(--sda-paper) 42%, transparent) 100%); }
.sda-hero__inner { display: grid; grid-template-columns: 1.08fr .92fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; padding-block: clamp(3.5rem, 9vw, 7rem); min-height: min(660px, 86vh); }
.sda-hero__copy { max-width: 34rem; }
.sda-display { margin: 0; font: 600 var(--sda-display)/var(--sda-lh-display) var(--sda-serif); letter-spacing: var(--sda-ls-display); }
.sda-lead { max-width: 46ch; margin: 1.4rem 0 0; font: var(--sda-body)/var(--sda-lh-body) var(--sda-serif); }
.sda-actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 2rem; }
.sda-hero__art { justify-self: end; width: min(100%, 330px); }
/* The hero credit line: the piece is named in the whisper register under the
   frame, where the price, the chip and the inquiry link used to sit. */
.sda-hero__figure { margin: 0; }
/* The one copper edge on the site: a hairline, a night gap, then the faintest
   copper halo. This is the featured slot's badge now that a night mat cannot
   distinguish it from the page. */
.sda-hero__figure .sda-frame { display: block; box-shadow:
  0 0 0 1px var(--sda-copper),
  0 0 0 5px var(--sda-night),
  0 0 0 6px color-mix(in srgb, var(--sda-copper) 35%, transparent),
  var(--sda-mat-shadow-lift); }
.sda-hero__figure figcaption { margin-top: .8rem; }
/* The claim bar: the studio's one factual boast, ruled off in copper. */
.sda-claim { display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; align-items: baseline; margin: 2rem 0 0; padding-top: 1rem; border-top: var(--sda-rule-warm); }
.sda-claim span { font: 500 var(--sda-label)/1.4 var(--sda-sans); letter-spacing: var(--sda-ls-label); text-transform: uppercase; color: var(--sda-copper); }
.sda-claim em { font-family: var(--sda-serif); font-size: .95rem; color: var(--sda-ink-soft); }
.sda-trust { border-block: var(--sda-rule); display: grid; grid-template-columns: repeat(3, 1fr); }
.sda-trust__item { padding: 1.1rem clamp(1rem, 3vw, 3rem); border-right: var(--sda-rule); }
.sda-trust__item:last-child { border-right: 0; }
.sda-trust__item strong { display: block; font: 600 1.05rem/1.2 var(--sda-serif); }
.sda-trust__item span { display: block; margin-top: .25rem; color: var(--sda-ink-soft); font: .78rem/1.4 var(--sda-sans); }
.sda-heading { max-width: 700px; }
.sda-heading h1, .sda-heading h2 { margin: 0; }
.sda-heading p:not(.sda-eyebrow) { max-width: 56ch; margin: 1rem 0 0; font-family: var(--sda-serif); color: var(--sda-ink-soft); }
/* auto-fit, not a fixed three: the row went from three tiles to five when
   Finished pieces split into Pendants, Earrings and Rings, and it grows again
   the day cabochons publish. A fixed count would leave a hole in the row. */
.sda-tile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-top: 2rem; }
/* A category tile is a photograph you walk into, so the photograph runs to the
   edge and the label is laid over it under a gradient rather than pressed on
   as a paper chip. The cream mat came off with the product frames on
   2026-07-31: a tile is the one place on the site where cropping IS wanted,
   because the subject is the category and not the piece, so there is no
   letterbox to fill and a cream border was doing nothing but drawing a box. */
.sda-tile { min-height: 300px; display: flex; align-items: end; text-decoration: none; color: var(--sda-ink); background: var(--sda-night); position: relative; overflow: hidden; border: 0; border-radius: var(--sda-radius); box-shadow: var(--sda-mat-shadow); }
.sda-tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform var(--sda-t-hover-out) var(--sda-ease-lift); }
@media (hover: hover) and (prefers-reduced-motion: no-preference) { .sda-tile:hover img { transform: scale(1.04); transition-duration: var(--sda-t-hover-in); } }
/* The gradient is the label's ground. Without it a serif in cream lands on
   whatever the photograph happens to be doing at the bottom of the frame,
   which for a stone on a light bench is cream on cream. */
.sda-tile span { position: relative; width: 100%; display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; padding: 3rem .95rem .85rem; color: var(--sda-ink); font: 600 1.15rem/1.1 var(--sda-serif); background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--sda-night) 88%, transparent) 62%, color-mix(in srgb, var(--sda-night) 94%, transparent)); }
/* How many are in there, in the whisper register. A tile that names a category
   without saying how deep it goes is asking for a click on trust. */
.sda-tile span em { font: 400 .76rem/1 var(--sda-sans); font-style: normal; letter-spacing: .04em; color: var(--sda-ink-soft); font-variant-numeric: tabular-nums; }
.sda-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1rem, 2vw, 1.6rem); margin-top: 2rem; }
.sda-grid--three { grid-template-columns: repeat(3, 1fr); }
/* `min-height: 5rem` used to hold the loose type block to one height across a
   row. The card is a flex column with a bottom-anchored control now, so the
   row equalises itself and a floor here only opens a gap under short names. */
.sda-card__stone { display: block; }
.sda-feature { display: grid; grid-template-columns: .8fr 1.2fr; gap: clamp(2rem, 7vw, 6rem); align-items: center; border-block: var(--sda-rule); }
/* The hairlines were how this band said "I am a band" on a flat ground. Inside
   a vignette the photograph and its scrim say it, and two rules across a
   photograph read as a scratch on the print. */
.sda-vignette .sda-feature { border-block: 0; }
/* Capped, which it did not need to be while the page was paper: a mat is now a
   light source, and an uncapped card here put a 700px cream slab in the middle
   of the page that outshouted the hero. */
.sda-feature .sda-card { max-width: 460px; justify-self: end; width: 100%; }
.sda-feature__copy { max-width: 42ch; }
.sda-feature__copy p { font-family: var(--sda-serif); }
/* The band's ground moved out of this rule on 2026-08-05: it is a
   `.sda-zone--cool` now, so the temperature alternation is stated once in the
   markup instead of once per band here. The class survives because the grid
   below it is the band's real job.
   Its photograph is the one thing in this band that stays FULL COLOUR: it is
   matted foreground work, not a ground. */
.sda-workshop__inside { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: center; }
.sda-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem; margin-top: 2rem; counter-reset: steps; }
/* Two routes, not three steps: the homepage band describes a fork (buy it, or
   have it made), and a fork rendered in three equal columns reads as a queue. */
.sda-steps--pair { grid-template-columns: repeat(2, 1fr); gap: 2.6rem; }
/* No 01 / 02 on a fork. The counter says "do this, then that", and these are
   two alternatives: one of them is the whole of your route, not its first leg. */
.sda-steps--pair .sda-step::before { content: none; }
.sda-steps--pair .sda-step h3 { margin-top: 0; }
.sda-step { border-top: var(--sda-rule); padding-top: 1rem; counter-increment: steps; }
/* Copper, not verdigris: the numerals are the one place the second accent does
   structural work, and it keeps verdigris meaning "a thing you can click". */
.sda-step::before { content: "0" counter(steps); color: var(--sda-copper); font: 500 var(--sda-label)/1 var(--sda-sans); letter-spacing: var(--sda-ls-label); }
.sda-step h3 { margin: .6rem 0; }
.sda-step p, .sda-show p { margin: 0; font-family: var(--sda-serif); color: var(--sda-ink-soft); }
.sda-shows { border-top: var(--sda-rule); }
.sda-show { display: grid; grid-template-columns: 1.2fr .8fr .8fr; gap: 1rem; padding: 1rem 0; border-bottom: var(--sda-rule); }
.sda-show strong { font-family: var(--sda-serif); }
/* --sda-night is the DEEPEST ground now (espresso), not the only dark one, so
   a .sda-night band still reads as a band: it steps down from the page rather
   than inverting it. The footer is the main one. */
.sda-night { background: var(--sda-night); color: var(--sda-night-ink); }
.sda-night .sda-eyebrow { color: var(--sda-verdigris); }
.sda-night .sda-lead, .sda-night p { color: color-mix(in srgb, var(--sda-night-ink) 75%, transparent); }
/* ---------- The one cream band ----------
   The concept keeps a single mat-coloured band, at the bottom of the page,
   where the site stops showing and starts asking. Everything inside it flips:
   the accents drop to their -deep values and the button becomes --dark.

   Read the selectors: every one of them names a class. There is deliberately
   no `.sda-cream a { color: ... }` here. That selector is (0,1,1) and would
   outrank `.sda-btn--dark` (0,1,0), which is precisely how the night concept
   first shipped a band full of buttons whose labels could not be seen. The
   same discipline covers `.sda-dialog`, which is a mat holding a photograph
   and a Close button. */
.sda-cream { background: var(--sda-mat); color: var(--sda-mat-ink); }
.sda-cream h1, .sda-cream h2, .sda-cream h3 { color: var(--sda-mat-ink); }
.sda-cream .sda-eyebrow { color: var(--sda-verdigris-deep); }
.sda-cream .sda-lead, .sda-cream p:not(.sda-eyebrow) { color: color-mix(in srgb, var(--sda-mat-ink) 78%, transparent); }
.sda-cream .sda-link-tertiary { color: var(--sda-verdigris-deep); }
.sda-cream .sda-link-tertiary:hover { border-bottom-color: var(--sda-verdigris-deep); }
.sda-cream .sda-caption { color: color-mix(in srgb, var(--sda-mat-ink) 70%, transparent); }
.sda-cream :focus-visible { outline-color: var(--sda-verdigris-deep); }
/* `.sda-dialog` was in this pair until 2026-07-31 and had to leave with the
   lightbox's cream: a secondary button in there now sits on the deepest
   ground, where mat-ink is unreadable. The default cream-on-night variant is
   already right for it, so it needs no rule at all rather than a corrected one. */
.sda-cream a.sda-btn--secondary, .sda-cream button.sda-btn--secondary {
  color: var(--sda-mat-ink); border-color: color-mix(in srgb, var(--sda-mat-ink) 45%, transparent); }
.sda-cream a.sda-btn--secondary:hover, .sda-cream button.sda-btn--secondary:hover {
  background: var(--sda-mat-ink); color: var(--sda-mat); border-color: var(--sda-mat-ink); }
.sda-footer { padding-top: var(--sda-space-band); }
.sda-footer__grid { display: grid; grid-template-columns: 1.35fr .75fr .75fr 1.2fr; gap: 2rem; }
.sda-footer h2 { font-size: 1rem; }
.sda-footer p, .sda-footer li { color: color-mix(in srgb, var(--sda-night-ink) 75%, transparent); font-family: var(--sda-serif); }
.sda-footer ul { padding: 0; margin: .8rem 0 0; list-style: none; }
.sda-footer li { margin: .35rem 0; }
.sda-footer a { text-decoration: none; }
.sda-subscribe { display: flex; gap: .5rem; margin-top: 1rem; }
/* A well, not a transparent outline: on espresso a see-through field reads as
   a caption with a box round it rather than something to type in. */
.sda-subscribe .sda-input { flex: 1; min-width: 0; background: var(--sda-well); color: var(--sda-night-ink); border-color: color-mix(in srgb, var(--sda-night-ink) 30%, transparent); }
.sda-subscribe .sda-input::placeholder { color: color-mix(in srgb, var(--sda-night-ink) 60%, transparent); }
.sda-footer__legal { margin-top: 3rem; padding: 1.2rem 0; border-top: 1px solid color-mix(in srgb, var(--sda-night-ink) 25%, transparent); display: flex; justify-content: space-between; gap: 1rem; color: color-mix(in srgb, var(--sda-night-ink) 65%, transparent); font: .75rem/1.4 var(--sda-sans); }
.sda-page-head { padding-block: var(--sda-space-band); border-bottom: var(--sda-rule); }
.sda-page-head p { max-width: 56ch; margin: 1rem 0 0; font-family: var(--sda-serif); color: var(--sda-ink-soft); }
/* ---------- The collection band ----------
   /catalog only, and deliberately not `.sda-page-head` itself: the archive,
   the cart and the preferences pages share that class and a photograph behind
   a receipt is decoration. This is the homepage hero's move (a photograph bled
   full width under a warm scrim) at a page head's height.

   Bleeding it means the band cannot live inside `.sda-container`, so the
   template splits: the band is its own full-width section and the container
   starts again at the filter rail.

   Two things the scrim has to do, in this order of importance:
     1. carry the copy. The type sits left, so the horizontal layer is nearly
        opaque there and lets the case show through on the right.
     2. hand back to the page. The last stop mixes toward --sda-paper, the page
        ground, NOT --sda-night: a band that ends on the deepest ground reads
        as a panel dropped onto the page instead of a part of it. The site is
        espresso end to end and this is the one place that distinction shows. */
.sda-pagehero { position: relative; isolation: isolate; overflow: hidden; background: var(--sda-night); border-bottom: var(--sda-rule); }
.sda-pagehero__bg { position: absolute; inset: 0; z-index: -2; }
/* The source is 1200 wide and the band is wider than that on any desktop, so
   cover scales it by WIDTH and only the vertical overflow is steerable: the x
   value does nothing here, and the brick wall at the right edge of the
   photograph cannot be cropped out. It is vignetted back down instead, by the
   first scrim layer below. The y value picks the slice: 22% lands the top
   shelf's pendants in the band, where a centred crop lands on bare shelf. */
.sda-pagehero__bg img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 22%; }
/* Mixed toward --sda-vignette for the reason given on .sda-hero__scrim above;
   the eyebrow over this band measured 4.45:1 while it was built out of night.
   The 180deg layer's last stop stays --sda-paper: that is the hand-back. */
.sda-pagehero__scrim { position: absolute; inset: 0; z-index: -1; background:
  linear-gradient(270deg,
    color-mix(in srgb, var(--sda-vignette) 80%, transparent) 0%,
    color-mix(in srgb, var(--sda-vignette) 0%, transparent) 30%),
  linear-gradient(180deg,
    color-mix(in srgb, var(--sda-vignette) 66%, transparent) 0%,
    color-mix(in srgb, var(--sda-vignette) 12%, transparent) 45%,
    color-mix(in srgb, var(--sda-paper) 94%, transparent) 100%),
  linear-gradient(94deg,
    color-mix(in srgb, var(--sda-vignette) 93%, transparent) 0%,
    color-mix(in srgb, var(--sda-vignette) 84%, transparent) 34%,
    color-mix(in srgb, var(--sda-vignette) 40%, transparent) 68%,
    color-mix(in srgb, var(--sda-vignette) 14%, transparent) 100%); }
.sda-pagehero__inner { position: relative; display: flex; flex-direction: column; justify-content: center; padding-block: clamp(2.6rem, 6vw, 4.2rem); min-height: min(360px, 46vh); }
/* Narrower than the 56ch the flat head allowed: the line has to clear the
   photograph, not just the column. */
.sda-pagehero__inner h1, .sda-pagehero__inner .sda-lead { max-width: 38rem; }
.sda-pagehero__inner .sda-lead { margin-top: 1.1rem; font-size: 1rem; color: var(--sda-ink-soft); }
/* ---------- Collection filters ----------
   Desktop uses a ruled editorial rail beside the work. Mobile keeps the same
   axes in a full-screen sheet with one Apply action at the bottom. */
.sda-catalog-layout { display: grid; grid-template-columns: minmax(13rem, 16rem) minmax(0, 1fr); gap: var(--sda-space-5); align-items: start; }
.sda-catalog-results { min-width: 0; }
.sda-rail { position: sticky; top: calc(var(--sda-mark-nav) + var(--sda-space-5)); max-height: calc(100vh - var(--sda-mark-nav) - var(--sda-space-6)); overflow-y: auto; padding-right: var(--sda-space-3); }
.sda-rail > .sda-eyebrow { margin-bottom: var(--sda-space-4); }
.sda-rail__group { padding-top: var(--sda-space-4); border-top: var(--sda-rule); }
.sda-rail__group + .sda-rail__group { margin-top: var(--sda-space-4); }
.sda .sda-rail__heading { margin: 0 0 var(--sda-space-2); font: 500 var(--sda-label)/1.3 var(--sda-sans); letter-spacing: var(--sda-ls-label); text-transform: uppercase; color: var(--sda-ink-soft); }
.sda-rail__options { border-top: var(--sda-rule); }
.sda-filter-link { display: flex; align-items: center; justify-content: space-between; gap: var(--sda-space-2); min-height: var(--sda-btn-h); padding: 0 var(--sda-space-2); border-bottom: var(--sda-rule); border-left: 2px solid transparent; color: var(--sda-ink-soft); text-decoration: none; font: 400 .9rem/1.35 var(--sda-sans); transition: color var(--sda-t-press) ease-out, border-color var(--sda-t-press) ease-out; }
.sda-filter-link:hover { color: var(--sda-ink); }
a.sda-filter-link.is-on { color: var(--sda-verdigris); border-left-color: var(--sda-verdigris); }
.sda-filter-link small { color: var(--sda-ink-faint); font-size: .76rem; font-variant-numeric: tabular-nums; }

.sda-results { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--sda-space-4); padding-bottom: var(--sda-space-3); border-bottom: var(--sda-rule); }
.sda-results__summary { display: flex; flex-wrap: wrap; gap: var(--sda-space-2) var(--sda-space-3); align-items: baseline; font: 400 .9rem/1.45 var(--sda-sans); color: var(--sda-ink-soft); }
.sda-results__summary [data-testid="catalog-result-count"] { color: var(--sda-ink); font-weight: 500; font-variant-numeric: tabular-nums; }
.sda-results__sort { display: flex; align-items: center; gap: var(--sda-space-2); flex: 0 0 auto; }
.sda-results__sort label { font: 500 var(--sda-label)/1.3 var(--sda-sans); letter-spacing: var(--sda-ls-label); text-transform: uppercase; color: var(--sda-ink-soft); }
.sda-results__sort .sda-select { min-height: var(--sda-btn-h); }
.sda-catalog-note { margin: var(--sda-space-5) 0 0; }

.sda-filter-float, .sda-filter-sheet { display: none; }

@media (max-width: 1023px) {
  .sda-catalog-layout { display: block; padding-bottom: calc(var(--sda-space-band) + var(--sda-btn-h) + var(--sda-space-4)); }
  .sda-rail { display: none; }
  .sda-filter-float { display: inline-flex; position: fixed; right: max(var(--sda-space-3), env(safe-area-inset-right)); bottom: max(var(--sda-space-3), env(safe-area-inset-bottom)); z-index: 50; box-shadow: var(--sda-mat-shadow); }
  .sda-filter-sheet.is-open { display: block; position: fixed; inset: 0; z-index: 70; overflow-y: auto; background: var(--sda-paper); }
  .sda-filter-sheet__form { min-height: 100%; display: flex; flex-direction: column; }
  .sda-filter-sheet__head { position: sticky; top: 0; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: var(--sda-space-3); padding: var(--sda-space-4); border-bottom: var(--sda-rule); background: var(--sda-paper); }
  .sda-filter-sheet__head .sda-eyebrow { margin-bottom: var(--sda-space-1); }
  button.sda-filter-sheet__close { min-height: var(--sda-btn-h); padding-inline: var(--sda-space-2); }
  .sda-filter-sheet__body { flex: 1; padding: 0 var(--sda-space-4) var(--sda-space-5); }
  .sda-filter-sheet__group { min-inline-size: 0; margin: 0; padding: var(--sda-space-5) 0 0; border: 0; }
  .sda-filter-sheet__group legend { width: 100%; margin: 0 0 var(--sda-space-2); padding: 0; font: 500 var(--sda-label)/1.3 var(--sda-sans); letter-spacing: var(--sda-ls-label); text-transform: uppercase; color: var(--sda-verdigris); }
  .sda-filter-option { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--sda-space-2); min-height: var(--sda-btn-h); border-top: var(--sda-rule); color: var(--sda-ink); cursor: pointer; font: 400 var(--sda-small)/1.35 var(--sda-sans); }
  .sda-filter-option:last-child { border-bottom: var(--sda-rule); }
  .sda-filter-option input { margin: 0; accent-color: var(--sda-verdigris); }
  .sda-filter-option small { color: var(--sda-ink-faint); font-size: .8rem; font-variant-numeric: tabular-nums; }
  .sda-filter-sheet__actions { position: sticky; bottom: 0; display: flex; align-items: center; gap: var(--sda-space-3); padding: var(--sda-space-3) var(--sda-space-4) max(var(--sda-space-3), env(safe-area-inset-bottom)); border-top: var(--sda-rule); background: var(--sda-paper); }
  .sda-filter-sheet__actions .sda-btn { flex: 1; }
  .sda-filter-sheet__clear { display: inline-flex; align-items: center; min-height: var(--sda-btn-h); padding-inline: var(--sda-space-2); }
  .sda-filter-sheet-open { overflow: hidden; }
  .sda-results { align-items: stretch; flex-direction: column; }
  .sda-results__sort { justify-content: space-between; }
  .sda-results__sort .sda-select { flex: 0 1 18rem; min-width: 0; }
}
.sda-empty { max-width: 50ch; padding: 3rem 0; font-family: var(--sda-serif); }
/* The way out of a rotating band: the handful above is a sample, this is the
   whole thing in order. Sits under the grid rather than beside the heading so
   it reads after the work, not instead of it. */
.sda-band-more { margin-top: 2rem; }
.sda-detail { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(280px, .8fr); gap: clamp(2rem, 6vw, 5rem); padding-block: var(--sda-space-band); }
/* 600, not 700. The published product photos are about 512x640, so a 700px
   stage was displaying every one of them above its own intrinsic width: the
   one thing Lane 2 and the legend both forbid outright. This comes back up
   when the pieces are re-shot at resolution. */
.sda-gallery__stage { max-width: 600px; cursor: zoom-in; }
/* The stage is a <button> so the lightbox is reachable from the keyboard. The
   frame supplies its background, radius and ratio; this only removes the
   chrome a button brings with it. The padding is zeroed rather than left out:
   `button.sda-gallery__stage` is (0,1,1) and beats `.sda-frame` (0,1,0), so a
   browser default would win here and inset the one photograph on the page that
   is the reason to visit it. Same reason it used to restate the mat. */
button.sda-gallery__stage { appearance: none; width: 100%; padding: 0; font: inherit; color: inherit; text-align: inherit; }
.sda-thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: .6rem; margin-top: .75rem; max-width: 600px; }
/* A thumbnail keeps an edge where the frames dropped theirs: four dark squares
   on a dark ground with no rule between them is one wide smudge, and the edge
   is also what shows which view is selected.

   THE RATIO BELONGS TO THE BOX, NOT TO THE IMAGE (2026-08-07). This slot used
   to read `.sda-thumb img { width: 100%; aspect-ratio: 1 }` and it never once
   drew a square: responsive_img emits width and height ATTRIBUTES for CLS, and
   a presentational height is still an explicit height, so `aspect-ratio` was
   ignored outright and every thumbnail rendered at its photo's full intrinsic
   height squeezed into a 136px column. On the Lander pendant that was a 136 x
   591 tower with the picture floating in the middle of it. Give the box the
   house ratio and let the image fill it, which is what every other slot in the
   kit already does (`.sda-frame`, `.sda-bag-thumb`, `.sda-inquire__thumb`).

   `picture { display: contents }` for the same reason those slots carry it:
   without it the <picture> is an inline box between the button and the image,
   percentage height has nothing definite to resolve against, and the image
   falls back to its intrinsic size. */
.sda-thumb { appearance: none; padding: 0; overflow: hidden; border: var(--sda-edge); border-radius: var(--sda-radius); background: var(--sda-frame-ground); cursor: pointer; display: block; aspect-ratio: var(--sda-frame-ratio); }
.sda-thumb:hover { border-color: var(--sda-ink-soft); }
.sda-thumb picture { display: contents; }
.sda-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.sda-detail__summary h1 { margin: .8rem 0; }
.sda-detail__summary > p { font-family: var(--sda-serif); }
.sda-detail .sda-price { display: block; margin: 1.5rem 0; font-size: 1.25rem; }
.sda-dossier { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 .8rem; margin-top: 1.7rem; }
/* The actions stack, and they need air between them: buttons are inline-flex,
   so with no gap "Add to my bag" and "Ask about this piece" sat directly on
   each other (Logan, 2026-08-07). align-items:start keeps each button the width
   of its own label rather than stretching across the column. */
.sda-inquiry-cta { margin-top: 1.5rem; display: flex; flex-direction: column;
  align-items: flex-start; gap: 0.85rem; }
.sda-inquiry-cta form { margin: 0; }
.sda-inquiry-cta .sda-reassure { margin-top: 0.15rem; }
/* The lightbox is the frame at full size, so it followed the frames off cream
   on 2026-07-31. A cream slab dropped over a night page was the brightest
   thing that ever appeared on the site, and it appeared by surprise.
   Its Close button therefore stops taking the on-mat treatment: those rules
   paint mat-ink, which on this ground is the invisible-label failure the whole
   cascade discipline in this file exists to prevent. */
.sda-dialog { max-width: min(92vw, 600px); max-height: 92vh; padding: .8rem; border: var(--sda-rule); border-radius: var(--sda-radius); background: var(--sda-frame-ground); color: var(--sda-ink); }
.sda-dialog::backdrop { background: color-mix(in srgb, var(--sda-night) 88%, transparent); }
.sda-dialog img { display: block; max-width: 100%; max-height: 84vh; width: auto; height: auto; object-fit: contain; }
.sda-dialog form { display: flex; justify-content: flex-end; margin-bottom: .6rem; }
.sda-related { padding-block: var(--sda-space-band); border-top: var(--sda-rule); }
.sda-scroll { display: flex; gap: 1rem; overflow-x: auto; scroll-snap-type: x mandatory; padding: 1rem 0; }
.sda-scroll .sda-card { flex: 0 0 min(70vw, 260px); scroll-snap-align: start; }
.sda-pairing { width: min(100% - 2rem, 760px); padding-block: var(--sda-space-band); }
.sda-pairing__head { max-width: var(--sda-measure-lead); margin-bottom: var(--sda-space-6); }
.sda-pairing__head h1 { margin-bottom: var(--sda-space-2); }
.sda-pairing__picture { width: 100%; margin: 0 0 var(--sda-space-6); }
.sda-pairing__frame { position: relative; width: 100%; }
.sda-pairing__frame [data-pairing-image] { position: absolute; inset: 0; opacity: 0; pointer-events: none; }
.sda-pairing__frame [data-pairing-image].is-active { opacity: 1; }
.sda-pairing__caption { display: flex; justify-content: space-between; gap: var(--sda-space-3); padding: var(--sda-space-3) 0; border-bottom: var(--sda-rule); }
.sda-pairing__caption p, figcaption.sda-pairing__caption { margin: 0; }
.sda-pairing__settings { margin-top: var(--sda-space-6); }
.sda-pairing__settings h2 { margin-bottom: var(--sda-space-3); }
.sda-pairing__tray { gap: var(--sda-space-4); margin: 0; padding-left: 0; border-block: var(--sda-rule); list-style: none; }
.sda-pairing__setting-item { flex: 0 0 min(68vw, 240px); }
.sda-pairing__setting { width: 100%; min-height: var(--sda-btn-h); padding: var(--sda-space-3) 0; border: 0; border-bottom: 1px solid transparent; background: none; color: var(--sda-ink); text-align: left; cursor: pointer; font: 400 1rem/1.35 var(--sda-serif); }
.sda-pairing__setting.is-active { border-bottom-color: var(--sda-ink); }
.sda-pairing__setting:focus-visible { outline: 2px solid var(--sda-verdigris); outline-offset: 3px; }
.sda-pairing__setting-thumb { display: block; width: 112px; margin-bottom: var(--sda-space-3); }
.sda-pairing__setting small { display: block; margin-top: .35rem; color: var(--sda-ink-soft); font: 400 var(--sda-label)/1.3 var(--sda-sans); font-variant-numeric: tabular-nums lining-nums; }
.sda-pairing__description { max-width: var(--sda-measure); margin-top: var(--sda-space-4); }
.sda-pairing__ending { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sda-space-3); margin-top: var(--sda-space-6); padding-top: var(--sda-space-5); border-top: var(--sda-rule); }
.sda-pairing__price { margin: 0; font-size: 1.25rem; }
button.sda-pairing__share { appearance: none; padding: 0; border: 0; background: none; font: inherit; cursor: pointer; }
@media (prefers-reduced-motion: no-preference) {
  .sda-pairing__frame [data-pairing-image] { transition: opacity 180ms ease-out; }
}
@media (max-width: 560px) {
  .sda-pairing__caption { display: block; }
  .sda-pairing__caption .sda-caption { margin-top: var(--sda-space-1); }
}
.sda-form { max-width: 620px; display: grid; gap: 1rem; margin-top: 2rem; }
.sda-form__piece { padding: 1rem 0; border-block: var(--sda-rule); font-family: var(--sda-serif); }
.sda-prose { padding-block: var(--sda-space-band); }
.sda-prose .prose > * + * { margin-top: 1.2rem; }
.sda-prose .prose p { color: var(--sda-ink-soft); }
.sda-dropcap::first-letter { float: left; padding: .08em .1em 0 0; font: 600 4rem/.75 var(--sda-serif); color: var(--sda-oxblood); }
.sda-login { width: min(100% - 2rem, 430px); margin: 5rem auto; }
.sda-login .sda-mark { margin: 0 auto 1rem; width: 72px; height: 72px; }
.sda-login form { display: grid; gap: 1rem; margin-top: 2rem; }
.sda-honeypot { position: absolute; left: -9999px; }
/* One column, and the scrim stops being a side-wash and becomes a top-to-bottom
   one: the photograph is behind the type at this width rather than beside it. */
/* One column, so the side-wash has nothing left to hold: every vignette band
   takes the --hold floor at this width, exactly as the hero and the collection
   band already switch to a vertical scrim. Written as one rule rather than
   restating the gradient, so the alpha floor cannot drift between the two. */
@media (max-width: 850px) { .sda-vignette .sda-vignette__scrim { background:
  linear-gradient(180deg,
    var(--sda-paper) 0%,
    var(--sda-vignette-none) var(--sda-seam),
    var(--sda-vignette-none) calc(100% - var(--sda-seam)),
    var(--sda-paper) 100%),
  linear-gradient(180deg,
    var(--sda-scrim-text) 0%,
    var(--sda-scrim-hold) 46%,
    var(--sda-scrim-text) 100%),
  radial-gradient(150% 112% at 50% 44%,
    var(--sda-vignette-core) 0%,
    var(--sda-vignette-mid) 58%,
    var(--sda-vignette-edge) 100%); } }
@media (max-width: 850px) { .sda-nav { display: none; } .sda-mobile { display: block; } .sda-hero__inner, .sda-feature, .sda-workshop__inside { grid-template-columns: 1fr; } .sda-hero__inner { min-height: 0; gap: 2.2rem; } /* Narrow keeps the x centred with the desktop rule now that the hero holds the tool bench: the 66% was pulling toward a person who is no longer in the picture. The y sits a little higher than desktop because a one-column hero is taller, so the same fraction of the frame reaches further down it. */ .sda-hero__bg img { object-position: 50% 50%; } .sda-hero__scrim { background: linear-gradient(180deg, color-mix(in srgb, var(--sda-vignette) 72%, transparent) 0%, color-mix(in srgb, var(--sda-vignette) 86%, transparent) 55%, color-mix(in srgb, var(--sda-vignette) 96%, transparent) 100%); } .sda-hero__art { justify-self: start; width: min(100%, 260px); } /* One column means the copy runs the full width, so the scrim that held it on the left has nothing left to hold: it goes vertical, the same way the homepage hero's does. */ .sda-pagehero__inner { min-height: 0; padding-block: clamp(2.2rem, 7vw, 3.2rem); } .sda-pagehero__scrim { background: linear-gradient(180deg, color-mix(in srgb, var(--sda-vignette) 74%, transparent) 0%, color-mix(in srgb, var(--sda-vignette) 88%, transparent) 52%, color-mix(in srgb, var(--sda-paper) 94%, transparent) 100%); } .sda-grid { grid-template-columns: repeat(2, 1fr); } .sda-tile-grid { grid-template-columns: repeat(2, 1fr); } .sda-tile { min-height: 220px; } .sda-footer__grid { grid-template-columns: repeat(2, 1fr); } .sda-detail { grid-template-columns: 1fr; } }
@media (max-width: 560px) { .sda-container { width: min(100% - 1.4rem, 1200px); } .sda-header__inner { min-height: 76px; } .sda-mark { width: 48px; height: 48px; } .sda-brand__name { font-size: .76rem; } .sda-hero__art { width: min(100%, 220px); } .sda-trust, .sda-steps, .sda-show { grid-template-columns: 1fr; } .sda-trust__item { border-right: 0; border-bottom: var(--sda-rule); } .sda-trust__item:last-child { border-bottom: 0; } .sda-grid { gap: 1rem; } .sda-footer__grid { grid-template-columns: 1fr; } .sda-footer__legal { flex-direction: column; } .sda-subscribe { flex-direction: column; } /* The thumbnail strip stays a strip on a phone. It used to stack one per row here, which was a workaround for the broken thumbnail above: four intrinsic-height towers at 80px wide were unreadable, so they were given the full width instead. With the box carrying the house ratio, a full-width thumbnail is a SECOND STAGE sitting under the first, 352 x 440 on a 390px phone. Four columns at this width is an 81px tile, well past the 48px tap target and the shape of every other contact strip on the site. */ .sda-dossier { grid-template-columns: 1fr; } }

/* ===================== WO-A1: home + collection round (2026-08-06) ===================== */

/* The creed line. The three-claim trust row unboxed into one sentence the
   studio says about itself: small caps, copper middle dots, a hairline above
   and below, and air. The rules are the structure; there are no panels. */
.sda-creed { text-align: center; margin: 0 auto; max-width: 920px;
  padding: clamp(1.5rem, 4vw, 2.3rem) 1rem;
  border-top: var(--sda-rule); border-bottom: var(--sda-rule);
  font-variant-caps: all-small-caps; letter-spacing: .22em;
  font-size: clamp(1.05rem, 2.2vw, 1.35rem); color: var(--sda-ink); }
.sda-creed__phrase { white-space: nowrap; }
.sda-creed__dot { color: var(--sda-copper); margin-inline: clamp(.5em, 2vw, .95em); }
@media (max-width: 560px) {
  /* Three stacked lines on a phone: the dots are a horizontal device and a
     nowrap phrase mid-line is how a page starts scrolling sideways. */
  .sda-creed__phrase { display: block; }
  .sda-creed__dot { display: none; }
}

/* The catalog band, reframed. The colour case photograph was being magnified
   about 1.6x by `cover` in a 360px band; taller band + a crop that lands on
   the top shelf instead of a slice of the middle.

   RE-AIMED 2026-08-07 with the photograph itself. 26% was pointing at the top
   shelf of the OLD case shot; on Linda's table the top of the frame is Les's
   painting on the wall, so the band opened on a picture of a picture with the
   pendants sliding off the bottom edge. 74% holds the necklace stands and the
   tray of cabochons, and lets the bottom of the painting sit above them where
   it belongs, which is roughly what a person sees walking up to that table. */
.sda-pagehero--case .sda-pagehero__inner { min-height: min(440px, 58vh); }
.sda-pagehero--case .sda-pagehero__bg img { object-position: 50% 74%; }
/* The colour photograph is brighter than the sepia grounds the base scrim was
   mixed for; the small eyebrow was reading 3.9:1. The case band's scrim works
   harder so the type clears 4.5 without touching the type tokens. */
.sda-pagehero--case .sda-pagehero__scrim { background:
  linear-gradient(180deg,
    color-mix(in srgb, var(--sda-vignette) 84%, transparent) 0%,
    color-mix(in srgb, var(--sda-vignette) 90%, transparent) 52%,
    color-mix(in srgb, var(--sda-paper) 96%, transparent) 100%); }

/* A matted stone print in the provenance band: foreground photography on a
   sepia ground, so it carries the mat, and the mat belongs to it alone. */
.sda-stone-print { width: min(100%, 380px); justify-self: end; }
.sda-stone-print img { display: block; width: 100%; height: auto;
  box-shadow:
    0 0 0 1px var(--sda-copper),
    0 0 0 5px var(--sda-night),
    0 0 0 6px color-mix(in srgb, var(--sda-copper) 35%, transparent),
    var(--sda-mat-shadow-lift); }
@media (max-width: 850px) { .sda-stone-print { justify-self: start; } }

/* ===================== WO-A2: story round (2026-08-06) ===================== */
/* ---------- /story: the mounted plate ----------
   The story page shipped with no photograph on it at all, which is the one
   page on the site whose whole job is to say how the work gets made. It gets
   photography as PLATES: prints mounted on the page beside the copy, not
   grounds bled under type. Nothing on this page carries a sentence over a
   picture, so there is no scrim here and no contrast arithmetic to redo; the
   prose keeps its own 68ch measure and the pictures sit next to it.

   Why this is not `.sda-frame`. That class is the PRODUCT frame: a fixed 4:5
   box that letterboxes whatever it is given, and a suite-wide guard asserts
   that no sepia asset ever appears inside one (the sepia round's central
   distinction is grounds-are-brown, foreground-work-keeps-its-colour). A
   plate is the opposite shape of problem: it is one specific photograph at its
   own aspect, so it takes no ratio at all and cannot letterbox.

   Which is also the whole no-distortion story. The mount sets no height and no
   aspect-ratio; the image is `width: 100%; height: auto` and carries the
   intrinsic `width`/`height` attributes that `_img.html` writes from the file
   on disk. The rendered box is therefore the photograph's own aspect by
   construction, not by a ratio somebody has to keep in sync with the asset,
   and it also reserves the right box before the bytes land. The three sources
   are 1200 to 1600px wide and the widest slot here is 940px, so none of them
   is ever shown past native size.

   The device itself is a family album page: a hairline warm edge, four gummed
   corner mounts in kraft, and an inset vignette off the shared
   --sda-vignette-* stops, which are the LIGHT half of that token family (dark
   corners, the middle of the picture left alone). Same black point as every
   other photograph on the site, so a plate falls away at its edge rather than
   ending on a line. */
.sda-story > * + * { margin-top: clamp(2.5rem, 5vw, 4.25rem); }
/* A spread is one prose column and one plate, and the plate changes sides down
   the page. The prose column is the wide one and caps itself at --sda-measure
   (`.sda .prose`), so at any container width the measure is the type's own,
   never the column's: the grid can only ever give it more room than it takes.
   Fractions rather than a fixed rail, so the plate scales with the page. */
.sda-story__spread { display: grid; align-items: start; gap: clamp(1.75rem, 4.5vw, 3.75rem); }
.sda-story__spread--right { grid-template-columns: minmax(0, 1fr) minmax(0, 0.6fr); }
.sda-story__spread--left { grid-template-columns: minmax(0, 0.6fr) minmax(0, 1fr); }
/* Dropped below the heading it sits beside. Aligned flush to the top of the
   eyebrow the page reads as two columns starting together, which is the boxy
   arrangement this round exists to avoid. */
.sda-story__spread--right .sda-plate { margin-top: clamp(0.5rem, 4vw, 3.25rem); }
.sda-plate {
  margin: 0;
  /* Kraft and gilt are mixed from tokens, never typed as hex. Kraft is the
     copper accent pulled down into the mat's ink so it reads as gummed paper
     rather than as a bright chip. Gilt is the same accent lifted toward cream:
     --sda-copper itself measures 4.32:1 on the page ground, which is under the
     floor for a caption-sized lead-in, and this lands at 5.6:1. */
  --sda-plate-kraft: color-mix(in srgb, var(--sda-copper) 62%, var(--sda-mat-ink));
  --sda-plate-gilt: color-mix(in srgb, var(--sda-copper) 78%, var(--sda-mat));
}
/* The one full-column moment on the page, where the copy turns from where the
   material comes from to what happens to it. Capped at 940 so the committed
   960px derivative still covers it at 1x and the 1600px original is never
   displayed beyond native width. */
.sda-plate--wide { width: min(100%, 940px); margin-inline: auto; }
.sda-plate__mount {
  position: relative; display: block; overflow: hidden;
  border: var(--sda-rule-warm); border-radius: var(--sda-radius);
  background: var(--sda-frame-ground); box-shadow: var(--sda-mat-shadow);
}
/* Descendant, not child: a responsive image arrives wrapped in <picture>, and
   picture is display:contents, so the <img> is the mount's own layout box.
   `height: auto` is the load-bearing half of the no-distortion rule; the
   object-fit is belt and braces for the day someone gives the mount a height. */
.sda-plate__mount img { display: block; width: 100%; height: auto; object-fit: contain; }
.sda-plate__mount picture { display: contents; }
.sda-plate__vignette { position: absolute; inset: 0; pointer-events: none; background:
  radial-gradient(112% 104% at 50% 46%,
    var(--sda-vignette-none) 0%,
    var(--sda-vignette-core) 46%,
    var(--sda-vignette-mid) 79%,
    var(--sda-vignette-edge) 100%); }
/* Album corners: one square per corner, clipped to the triangle a gummed paper
   mount actually is, with its hypotenuse facing the middle of the picture. CSS
   only, no asset, and `aspect-ratio: 1` keeps them square at every width so the
   four of them never disagree. */
.sda-plate__corner {
  position: absolute; width: clamp(17px, 2.4vw, 26px); aspect-ratio: 1;
  background: var(--sda-plate-kraft); pointer-events: none;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sda-mat) 16%, transparent);
}
.sda-plate__corner--tl { top: 0; left: 0; clip-path: polygon(0 0, 100% 0, 0 100%); }
.sda-plate__corner--tr { top: 0; right: 0; clip-path: polygon(0 0, 100% 0, 100% 100%); }
.sda-plate__corner--bl { bottom: 0; left: 0; clip-path: polygon(0 0, 0 100%, 100% 100%); }
.sda-plate__corner--br { bottom: 0; right: 0; clip-path: polygon(100% 0, 100% 100%, 0 100%); }
/* The caption is the whisper register: `.sda-caption` already carries italic
   serif at caption size in soft ink, so this only sets the measure and the
   lead-in. The lead-in is small caps rather than the letterspaced uppercase
   Hanken label, which the legend keeps off the serif; the separator is
   generated so the caption's text content stays a sentence. */
.sda-plate__caption { margin: 0.85rem 0 0; max-width: 44ch; }
.sda-plate__lead { font-style: normal; font-variant-caps: all-small-caps;
  letter-spacing: 0.06em; color: var(--sda-plate-gilt); }
.sda-plate__lead::after { content: " \00b7 "; letter-spacing: normal; color: var(--sda-ink-faint); }
/* One column, so the plate stops being a column and becomes a print between
   two runs of copy. Capped, because a 92vw plate on a tablet is a page of
   photograph; the offset that dropped the top plate below its heading goes
   with the column it was offsetting against. */
@media (max-width: 850px) {
  .sda-story__spread--right, .sda-story__spread--left { grid-template-columns: minmax(0, 1fr); }
  .sda-story__spread--right .sda-plate { margin-top: 0; }
  .sda-plate--aside { width: min(100%, 460px); }
}

/* ===================== WO-A3: archive band (2026-08-06) ===================== */
/* The sold band that opens /archive.

   The page was type on a ground: "it doesn't have anything, you don't have any
   images going on in here" (Les, via Logan, 2026-08-06). What was blessed is a
   slow horizontal strip of sold work in the spirit of a film strip, and the
   thing that makes it worth building rather than filming is that it is fed by
   the archive query itself: a piece slides into it the day it sells.

   The mechanism, and the two places it goes wrong:

   1. The loop is ONE animation on a track that carries the strip twice
      (templates/archive.html), translating to -50%. At the wrap the second
      copy is standing exactly where the first one started, so there is no
      seam. This only holds while every cell is the same width AND the spacing
      lives INSIDE the cell: a flex `gap` puts one gap between the two copies
      and none at the wrap point, so -50% lands half a gap out and the strip
      visibly jumps once a cycle. Hence `padding-inline-end` on the cell and no
      gap on the track.
   2. Nothing here is JavaScript, so nothing here can stall a scroll. The pause
      is `animation-play-state` on hover, and it is a courtesy: on a phone
      there is no hover, and under reduced motion there is no animation to
      pause, which is why the reduced-motion state below is a real static row
      that a person can push with a finger rather than a frozen strip. */
.sda-archive-band { padding-block: clamp(2.5rem, 6vw, 4rem) clamp(2.2rem, 5vw, 3.2rem); }
.sda-archive-band__line { margin: 0; font: italic 400 var(--sda-h2)/1.12 var(--sda-serif); letter-spacing: var(--sda-ls-display); }
/* Full width, and it must stay outside `.sda-container`: a strip that stops at
   the 1200px measure is a widget on a page, and what was asked for is the
   piece passing THROUGH the room. `overflow: hidden` on this element is what
   keeps a track wider than the screen from scrolling the whole document
   sideways, which is the one way this band could break a phone. */
.sda-archive-band__viewport {
  margin-block: clamp(1.6rem, 4vw, 2.4rem); overflow: hidden;
  /* The edge fades, the same device the page uses elsewhere: the strip has no
     start and no end, so it must not appear to have one. Black here is a
     stencil and not a colour: `mask-image` reads the alpha channel, so opaque
     means "show this pixel". No ground is being painted, and the no-pure-black
     rule is untouched. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
}
.sda-archive-band__track { display: flex; width: max-content; }
.sda-archive-band__cell { flex: 0 0 auto; width: 230px; padding-inline-end: 1.5rem; display: flex; flex-direction: column; }
/* The house frame rule, unchanged, at a fixed film-strip size: the photograph
   is CONTAINED on the deepest ground and is never cropped to fill the box. The
   aspect-ratio override is the point of the modifier: `.sda-frame` is 4/5 and
   a column of portrait frames sliding past reads as a contact sheet rather
   than as a strip. The mat float comes off for the same reason a tile has no
   mat: twenty of them in a row is twenty shadows, so the copper hairline does
   the separating instead. */
.sda-archive-band__frame { aspect-ratio: auto; width: 230px; height: 180px; background: var(--sda-stage); border: var(--sda-rule-warm); box-shadow: none; }
.sda-archive-band__frame img { width: 100%; height: 100%; object-fit: contain; }
.sda-archive-band__name { margin-top: .7rem; font: 400 .95rem/1.25 var(--sda-serif); color: var(--sda-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sda-archive-band__year { margin-top: .25rem; font: 500 var(--sda-label)/1.2 var(--sda-sans); letter-spacing: var(--sda-ls-label); text-transform: uppercase; color: var(--sda-ink-faint); font-variant-numeric: tabular-nums; }
.sda-archive-band__whisper { margin: 0; max-width: 46ch; font: italic 400 var(--sda-caption)/var(--sda-lh-caption) var(--sda-serif); color: var(--sda-ink-soft); }
@keyframes sda-archive-drift { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-50%, 0, 0); } }
@media (prefers-reduced-motion: no-preference) {
  .sda-archive-band__track { animation: sda-archive-drift 50s linear infinite; }
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .sda-archive-band__viewport:hover .sda-archive-band__track { animation-play-state: paused; }
}
/* Reduced motion: not a frozen strip, a shelf. The animation is never applied
   above, and the overflow becomes the reader's to push, so the pieces past the
   edge are still reachable rather than merely stopped. */
@media (prefers-reduced-motion: reduce) {
  .sda-archive-band__track { animation: none; transform: none; }
  .sda-archive-band__viewport { overflow-x: auto; }
}
@media (max-width: 560px) {
  .sda-archive-band__cell { width: 176px; padding-inline-end: 1rem; }
  .sda-archive-band__frame { width: 176px; height: 138px; }
}

/* ===================== WO-A4: bag presence (2026-08-06) ===================== */

/* Two things, both small, both about the same complaint: a customer added a
   piece and the site gave them no lasting sign of it, then showed them a bag
   that was a list of names.

   1. THE HEADER. The design legend bans cart iconography outright, so the
      presence is the word "Bag" and a count, sitting in the nav's own register
      because it IS a nav link, not a widget dressed as one. There is almost
      nothing to style: the markup is a direct-child <a> of .sda-nav, which
      already owns type, size and gap.

      Colour is deliberately NOT set here. `.sda-nav > a:not(.sda-btn)` is
      (0,2,0) and owns every nav link's colour; a `color` on this (0,1,0)
      selector would be dead the moment it was written, which is the exact trap
      the comment beside that rule was left for. The count is tabular so the
      word does not shuffle sideways as pieces go in, and nowrap so "Bag" never
      ends a line with its own number on the next one. */
.sda-nav__bag { white-space: nowrap; font-variant-numeric: tabular-nums; }

/* 2. THE BAG LINE. It carries the piece's photograph now.

      The thumb obeys the house frame rule rather than a fixed crop: the photo
      is CONTAINED on the deepest ground, at whatever aspect it was shot, and
      the ground shows wherever it does not reach. Same construction as the
      piece-page thumbs (`.sda-thumb`). A cover crop at 84px would be the only
      place on this site that cuts a stone, and it would cut them worst exactly
      where the shot is landscape, which is a third of the catalog. */
.sda-bag-line__lead { display: flex; align-items: center; gap: .9rem; min-width: 0; }
/* `.sda-card__row` (components.css) aligns its children on the first baseline,
   which is right for two lines of type and wrong the moment one side is an
   84px picture: the photograph would hang off the name's baseline. Equal
   specificity, but public.css loads after components.css, so this wins. */
.sda-bag-line { align-items: center; }
.sda-bag-thumb {
  flex: 0 0 auto; width: 84px; height: 84px; display: block; overflow: hidden;
  border: var(--sda-edge); border-radius: var(--sda-radius);
  background: var(--sda-frame-ground);
}
/* Descendant, not child: a responsive image arrives wrapped in <picture>, and
   `picture` is display:contents, so the <img> is still the box's layout child. */
.sda-bag-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.sda-bag-thumb picture { display: contents; }
/* A sold line keeps its photograph and loses its emphasis. The whole point of
   leaving it on the list is to tell somebody WHICH piece went, and a name they
   half remember does that far worse than the picture they were looking at. */
.sda-bag-thumb--gone { opacity: .5; }

/* ===== WO-A6 find us ===== */
/* /find-us, the nav's Find Us destination (2026-08-06).

   The link was `/#shows` and landed a visitor two thirds of the way down the
   homepage, in a strip of names and dates. The page it points at now runs
   paper, cool, warm, paper: a typographic opening, the dates, the table and
   its photograph, the close.

   Nothing here is scoped to `body.sda` because nothing here is an element
   selector. That scoping exists in this file for the one `body` rule at the
   top: public.css is also linked from the internal form editor, so a bare
   element rule would leak into a staff screen. Class selectors cannot, and
   every rule below names a class this page is the only user of. Same reason
   none of them sets `color` on a bare `a`: that would be (0,1,1) and would
   outrank the button variants. */

/* The opening. The lead runs a little wider than the hero's 46ch because it is
   the only thing on this ground and has no photograph beside it to balance. */
.sda-findus__open .sda-display { margin-top: .8rem; }
.sda-findus__open .sda-lead { max-width: 52ch; }

/* ---------- The dates: ruled rows, never cards ----------
   Text is not boxed on this site. The structure is one hairline above the list
   and one under each entry, which is the same device the homepage shows band
   has always used, at the scale of a page that is ABOUT the dates: the row
   pads to nearly 2rem top and bottom so four entries read as a printed
   schedule rather than as a table.

   Auto-placement does the layout. Name, city and dates fill the three columns
   of the first row; the note has nowhere left to go and drops to the second
   row under the name, which is exactly where it belongs. No explicit
   grid-column anywhere, so an entry without a note simply has no second row. */
.sda-dates { list-style: none; margin: clamp(1.8rem, 4vw, 2.75rem) 0 0; padding: 0;
  border-top: var(--sda-rule); }
.sda-date { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, .75fr) minmax(0, .9fr);
  gap: .55rem clamp(1rem, 3vw, 2.5rem); align-items: baseline;
  padding-block: clamp(1.4rem, 3.2vw, 2.1rem); border-bottom: var(--sda-rule); }
/* Large serif, and deliberately lighter than the 600 the heading elements
   carry: a schedule of six bold lines reads as six headlines competing. */
.sda-date__name { margin: 0; font: 400 var(--sda-h2)/var(--sda-lh-h2) var(--sda-serif);
  letter-spacing: var(--sda-ls-h2); }
/* The one Hanken run on the row. City and state are a LABEL, the thing an eye
   scans for, so it takes the label register; everything else here is a
   sentence and stays in the serif. */
.sda-date__where { margin: 0; font: 500 var(--sda-label)/1.4 var(--sda-sans);
  letter-spacing: var(--sda-ls-label); text-transform: uppercase; color: var(--sda-ink-soft); }
/* Tabular figures so a column of date ranges lines up on its numerals. */
.sda-date__when { margin: 0; font: 400 var(--sda-small)/1.4 var(--sda-serif);
  color: var(--sda-ink); font-variant-numeric: tabular-nums; }
/* The whisper. Italic serif at caption size is the register the site uses for
   anything said quietly beside a fact, which is what a show note is. */
.sda-date__note { margin: 0; max-width: 52ch;
  font: italic 400 var(--sda-caption)/var(--sda-lh-caption) var(--sda-serif);
  color: var(--sda-ink-soft); }
/* Between shows, which is the state this page is in most of the year. Serif at
   reading size on the open ground: a passage, not a stub. */
.sda-between { max-width: 54ch; margin-top: clamp(1.4rem, 3vw, 2rem); }
.sda-between p { font: var(--sda-body)/var(--sda-lh-body) var(--sda-serif);
  color: var(--sda-ink-soft); margin: 0; }
.sda-between p + p { margin-top: 1.1rem; }

/* ---------- At the table, and the case print ---------- */
.sda-findus__table { display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.sda-findus__said { max-width: 44ch; }
.sda-findus__said .sda-lead { max-width: none; }
.sda-findus__said h2 { margin-top: .5rem; }
/* A mounted colour print: warm hairline, the deep ground behind it, and the
   matted float every photograph on this site sits on. No album corners; that
   device belongs to the story page's plates and this is one print, not a page
   from an album.

   The no-distortion story is the mount setting no height and no aspect-ratio.
   The image is `width: 100%; height: auto` and carries the intrinsic
   width/height attributes `_img.html` writes from the file on disk, so the
   rendered box IS the photograph's own aspect by construction, and the box is
   reserved before the bytes land. The source is 1200px wide against a 560px
   slot, so it is never shown past native size. */
.sda-case-print { margin: 0; }
.sda-case-print__mount { display: block; overflow: hidden;
  border: var(--sda-rule-warm); border-radius: var(--sda-radius);
  background: var(--sda-frame-ground); box-shadow: var(--sda-mat-shadow); }
/* Descendant, not child: a responsive image arrives wrapped in <picture>, and
   picture is display:contents, so the <img> is the mount's own layout box. */
.sda-case-print__mount img { display: block; width: 100%; height: auto; object-fit: contain; }
.sda-case-print__mount picture { display: contents; }
.sda-case-print figcaption { margin: .85rem 0 0; max-width: 40ch; }

/* ---------- The close ----------
   One hairline and air, which is all a closing block on this site gets. */
/* The homepage tie-in, which lives in this section because this round added it
   and the other lanes own their own. The shows band on the homepage is a
   summary now that the dates have a page: one tertiary link out of it, in the
   same idiom as the provenance band's "Read our story". */
.sda-shows__more { margin: 1.6rem 0 0; }

/* ---------- The close ----------
   One hairline and air, which is all a closing block on this site gets. */
.sda-findus__close { border-top: var(--sda-rule); padding-block: var(--sda-space-band-lg); }
.sda-findus__close h2 { margin-top: .5rem; }
.sda-findus__close .sda-lead { max-width: 50ch; }

@media (max-width: 850px) {
  /* One column, so the print stops being a column and becomes a print under
     the copy. Capped, because a 92vw photograph on a tablet is a page of
     photograph. */
  .sda-findus__table { grid-template-columns: minmax(0, 1fr); }
  .sda-case-print { width: min(100%, 560px); }
}
@media (max-width: 700px) {
  /* The three column row is the first thing to break on a phone: "February 3
     to 7, 2027" in a third of 350px wraps to three lines. Stacked, the entry
     reads name, place, dates, note, which is the order a person says it in. */
  .sda-date { grid-template-columns: minmax(0, 1fr); gap: .4rem; }
  .sda-date__where { margin-top: .15rem; }
}
@media (max-width: 560px) { .sda-bag-thumb { width: 64px; height: 64px; } .sda-bag-line__lead { gap: .7rem; } }


/* ===== WO-A7 inquire ===== */

/* /inquire is the checkout of an inquiry-first site. There is no cart control
   anywhere on the storefront by design, so this page is where every sale
   actually starts, and it shipped as the plainest page on the site: a centred
   prose column with three fields in it.

   The redesign is a frame, not a form change. Nothing below styles an input,
   a label or a button; `.sda-field`, `.sda-input` and `.sda-btn` already own
   all of that in components.css and are shared with /hello, /commissions and
   checkout. What is added here is the page around them: a heading with air, a
   second column that answers "what happens after I press this", and the piece
   itself shown rather than named in a parenthesis. */
.sda-inquire { padding-block: var(--sda-space-band); }
.sda-inquire__head { max-width: 34rem; }
.sda-inquire__head h1 { margin: 0; }
.sda-inquire__head .sda-lead { margin-top: 1.1rem; color: var(--sda-ink-soft); }

/* Form left, the quiet column right, and the form is FIRST in the source so a
   phone gets the thing it came to do before it gets the reassurance about it.
   850px is the site's own desktop breakpoint (the mobile menu, the vignette
   scrims and the piece page all turn over there), so the inquiry page turns
   over with them rather than inventing a width of its own.

   `space-between` rather than a fractional right track: the form is capped at
   620px by `.sda-form` and the aside is a whisper, so filling a 1200px
   container with two stretched columns would make the aside as loud as the
   form. Two measured columns with the air between them is the register. */
.sda-inquire__cols { display: grid; gap: clamp(2.4rem, 5vw, 3.2rem);
  margin-top: clamp(2rem, 5vw, 3rem); align-items: start; }
.sda-inquire__main { min-width: 0; }
@media (min-width: 850px) {
  .sda-inquire__cols { grid-template-columns: minmax(0, 620px) minmax(240px, 20rem);
    justify-content: space-between; gap: clamp(3rem, 7vw, 6rem); }
}

/* ---------- the piece row ----------
   Hairlines above and below, no panel: text is never boxed, and this row is
   mostly text. The mat belongs to the photograph alone and is the bag-line
   thumb at a slightly larger size, `contain` and all, so the same stone is the
   same shape in the card, the bag and here. */
.sda-inquire__piece { display: flex; align-items: center; gap: 1.1rem;
  padding: 1.2rem 0; border-block: var(--sda-rule); min-width: 0; }
.sda-inquire__thumb { flex: 0 0 auto; width: 112px; height: 112px; display: block;
  overflow: hidden; border: var(--sda-edge); border-radius: var(--sda-radius);
  background: var(--sda-frame-ground); }
/* Descendant, not child: a responsive image arrives wrapped in <picture>, and
   `picture` is display:contents, so the <img> is still the box's layout child. */
.sda-inquire__thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.sda-inquire__thumb picture { display: contents; }
.sda-inquire__piece-text { min-width: 0; }
.sda-inquire__piece p { margin: 0; }
.sda-inquire__label { margin-bottom: .4rem; font: 500 var(--sda-label)/1.3 var(--sda-sans);
  letter-spacing: var(--sda-ls-label); text-transform: uppercase; color: var(--sda-ink-soft); }
.sda-inquire__piece .sda-card__stone { margin-top: .3rem; }
.sda-inquire__main .sda-form { margin-top: 1.8rem; }
@media (max-width: 560px) { .sda-inquire__thumb { width: 84px; height: 84px; } }

/* ---------- what happens next ----------
   Deliberately NOT `.sda-steps` / `.sda-step`, which is the home page's
   how-it-works row: that one counts itself with a copper `01` in ::before and
   lays out three across. Numerals here would be a checkout's progress bar, and
   this is the opposite of a checkout.

   Ruled, never carded. Every step carries one hairline under it and nothing on
   its sides, so the column is structured by rules and whitespace exactly like
   the creed line and the option groups in components.css. Any background on a
   step turns the column into three panels, which is the boxiness this whole
   round was called to remove. */
.sda-next__title { margin: 0; font: 500 var(--sda-label)/1.3 var(--sda-sans);
  letter-spacing: var(--sda-ls-label); text-transform: uppercase; color: var(--sda-ink-soft); }
.sda-next__steps { margin-top: 1.1rem; border-top: var(--sda-rule); }
.sda-next__step { padding: 1rem 0; border-bottom: var(--sda-rule); }
.sda-next__step p { margin: 0; font-family: var(--sda-serif); color: var(--sda-ink-soft); }
/* (0,2,0) over the (0,1,1) above, so the name is the full-strength ink and the
   sentence under it stays secondary. Written as two classes rather than an
   element qualifier because both lines are <p>. */
.sda-next__step .sda-next__name { color: var(--sda-ink); margin-bottom: .3rem; }
.sda-next .sda-reassure { display: block; margin: 1.3rem 0 0; }

/* ===== WO-A5 our stones ===== */

/* /stones: the specimen book.

   "Our Stones is a bare anchor snap" (Logan, 2026-08-05). The nav link went to
   `/#our-stones`, halfway down the homepage. This is the page it should have
   been, and its register is a field guide written by the people who cut the
   stones: type first, documents second, nothing decorative.

   Three rules are carried by the CSS below and each is one a later edit
   reaches for by accident.

   1. NOTHING HERE IS BOXED. The four-stage walk and the family guide are both
      structured entirely by hairlines and whitespace: a rule ABOVE a run of
      type, never a border around it. Both would look "tidier" as cards and
      both would then be the boxy failure the creed line was rebuilt to remove.
   2. EVERY PHOTOGRAPH IS CONTAINED. `.sda-specimen` and the guide plate set a
      ratio and `object-fit: contain`, and every asset on this page is 3:4 or
      4:3, so the ratio IS the file's own and the contain leaves no letterbox
      at all. The slab shots are documents with the cutting mat's ruler grid in
      frame; cropping to fill a box would cut the measurement out of the
      measurement photograph.
   3. THE MAT IS NOT A FRAME AND NOT A PLATE. `.sda-frame` is the 4:5 product
      frame with guards of its own, and `.sda-plate` is the story page's family
      album, gummed corners included. A specimen sheet is neither, so it has
      its own one-hairline device. */
body.sda .sda-stones-open { padding-block: var(--sda-space-band-lg) var(--sda-space-band); }
/* The headline and the lead are two columns rather than a stack, with the
   hairline running under the eyebrow across both: the page states its subject
   and answers it on the same line of the page, which is what a specimen book's
   title page does. */
body.sda .sda-stones-open__spread {
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(1.5rem, 5vw, 4rem); align-items: start;
  padding-top: clamp(1.2rem, 3.5vw, 2.2rem); border-top: var(--sda-rule);
}
body.sda .sda-stones-open h1 { max-width: 15ch; }
body.sda .sda-stones-open__lead p { margin: 0; max-width: 46ch;
  font: var(--sda-body)/var(--sda-lh-body) var(--sda-serif); color: var(--sda-ink-soft); }
body.sda .sda-stones-open__lead p + p { margin-top: 1.1rem; }

/* The specimen mat. No height and no ratio is set by the caller: the modifier
   picks the file's own aspect, so `contain` has nothing left over to letterbox
   and the intrinsic width/height attributes `_img.html` writes still reserve
   the right box before the bytes land. */
body.sda .sda-specimen {
  display: block; overflow: hidden;
  aspect-ratio: var(--sda-specimen-ratio, 3 / 4);
  border: var(--sda-rule-warm); border-radius: var(--sda-radius);
  background: var(--sda-frame-ground); box-shadow: var(--sda-mat-shadow);
}
/* Descendant, not child: a responsive image arrives wrapped in <picture>, and
   `picture` is display:contents, so the <img> is the mat's own layout box. */
body.sda .sda-specimen img { display: block; width: 100%; height: 100%; object-fit: contain; }
body.sda .sda-specimen picture { display: contents; }
body.sda .sda-specimen--wide { --sda-specimen-ratio: 4 / 3; }

/* The slab pair: two prints, one caption. Capped at 880 so each print lands
   near 420px, which keeps the committed 960px derivative comfortably above
   what is displayed and stops the pair becoming a page of photograph. */
body.sda .sda-slab-pair { margin: 0 auto; width: min(100%, 880px); }
body.sda .sda-slab-pair__prints { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(1rem, 3vw, 2rem); }
body.sda .sda-slab-pair__caption { margin: 1.1rem auto 0; max-width: 60ch; text-align: center; }

/* The walk. A hairline over each stage, a copper numeral, and air. Copper for
   the same reason the homepage steps use it: verdigris means "a thing you can
   click", and none of this is. */
body.sda .sda-walk {
  list-style: none; margin: clamp(1.8rem, 4vw, 2.6rem) 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.2rem, 3vw, 2.4rem); counter-reset: sda-walk;
}
body.sda .sda-walk__stage { border-top: var(--sda-rule); padding-top: 1rem; counter-increment: sda-walk; }
body.sda .sda-walk__stage::before { content: "0" counter(sda-walk); display: block;
  color: var(--sda-copper); font: 500 var(--sda-label)/1 var(--sda-sans); letter-spacing: var(--sda-ls-label); }
body.sda .sda-walk__stage h3 { margin: .7rem 0 .5rem; }
body.sda .sda-walk__stage p { margin: 0; font-family: var(--sda-serif); color: var(--sda-ink-soft); }
/* The people, in one sentence, under the whole walk rather than one name per
   stage. Jeremy primarily cuts and Les primarily facets, sets and does the
   metalwork, and both cross over; a name pinned to each stage would state a
   division of labour the studio does not have. */
body.sda .sda-walk__note { margin: clamp(1.6rem, 4vw, 2.4rem) 0 0; padding-top: 1.1rem;
  max-width: 64ch; border-top: var(--sda-rule);
  font-family: var(--sda-serif); color: var(--sda-ink-soft); }
body.sda .sda-docket { margin: clamp(2rem, 5vw, 3rem) auto 0; width: min(100%, 900px); }
body.sda .sda-docket figcaption { margin-top: .9rem; text-align: center; }

/* The family field guide: rows separated by hairlines, a small plate, the name
   in serif and the count as plain text. Three explicit columns, because the
   plate is optional and auto-placement would otherwise slide a nameless
   family's name into the picture's column and break the alignment down the
   page. */
/* Capped, and not at the container's 1200: a count parked a foot away from the
   name it belongs to stops being a row and becomes two columns of unrelated
   text. */
body.sda .sda-guide { list-style: none; margin: clamp(1.6rem, 4vw, 2.4rem) 0 0; padding: 0;
  width: min(100%, 940px); }
/* The row IS the link (2026-08-17), so `.sda-guide__row` moved off the <li> and
   onto an <a> inside it. Two consequences worth stating, because both are the
   kind of thing that breaks silently:

   1. `:last-child` had to move to the ITEM. On the <li> it meant "the last row";
      on the anchor it is always true, because the anchor is its item's only
      child, and every row would have grown a bottom rule.
   2. The anchor inherits colour and drops its underline. The row is three ruled
      fields and the hairlines do the structuring, so the affordance is the
      NAME taking the accent on hover, not a background tint. A tint here would
      box a run of text, which this site does not do. Colour only, no transform:
      a row is a card by another name and cards never scale. */
body.sda .sda-guide__item { display: block; }
body.sda .sda-guide__row {
  display: grid; grid-template-columns: 132px minmax(0, 1fr) auto;
  align-items: center; gap: clamp(1rem, 3vw, 2rem);
  padding-block: clamp(1rem, 2.5vw, 1.5rem); border-top: var(--sda-rule);
  color: inherit; text-decoration: none;
}
body.sda .sda-guide__item:last-child .sda-guide__row { border-bottom: var(--sda-rule); }
body.sda .sda-guide__row .sda-guide__name,
body.sda .sda-guide__row .sda-guide__count {
  transition: color var(--sda-t-press) var(--sda-ease-lift);
}
@media (hover: hover) {
  body.sda .sda-guide__row:hover .sda-guide__name { color: var(--sda-verdigris); }
  body.sda .sda-guide__row:hover .sda-guide__count { color: var(--sda-ink); }
}
body.sda .sda-guide__row:focus-visible .sda-guide__name { color: var(--sda-verdigris); }
body.sda .sda-guide__plate {
  grid-column: 1; width: 132px; aspect-ratio: 3 / 4; overflow: hidden;
  border: var(--sda-rule-warm); border-radius: var(--sda-radius);
  background: var(--sda-frame-ground);
}
/* A family with no hand-picked macro renders its row with no picture at all
   rather than borrowing another stone's. `display: none` and not a transparent
   box: the column is fixed on the row, so the alignment holds either way, and
   an empty mat with a ratio would otherwise hold a 176px hole open. */
body.sda .sda-guide__plate:empty { display: none; }
body.sda .sda-guide__plate img { display: block; width: 100%; height: 100%; object-fit: contain; }
body.sda .sda-guide__plate picture { display: contents; }
body.sda .sda-guide__name { grid-column: 2; margin: 0;
  font: 600 var(--sda-h3)/var(--sda-lh-h3) var(--sda-serif); color: var(--sda-ink); }
/* Hanken, because a count is data rather than a sentence, and tabular so a
   column of them lines up down the page. */
body.sda .sda-guide__count { grid-column: 3; margin: 0;
  font: 400 .9rem/1.3 var(--sda-sans); color: var(--sda-ink-soft);
  font-variant-numeric: tabular-nums; }
/* The one-offs, as a note rather than as rows. It sits under the last rule the
   list draws, in the serif because it is a sentence and not data, and it does
   not repeat the hairline: the list has already closed. */
body.sda .sda-guide__tail { margin: clamp(1rem, 2.5vw, 1.4rem) 0 0; max-width: 68ch;
  font: 400 var(--sda-small)/1.5 var(--sda-serif); color: var(--sda-ink-soft); }
body.sda .sda-guide__more { margin: clamp(1.6rem, 4vw, 2.2rem) 0 0; }

/* The closing band: the print at the left, the read at the right. */
body.sda .sda-reading { display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  gap: clamp(2rem, 6vw, 4.5rem); align-items: center; }
body.sda .sda-reading__print { margin: 0; width: min(100%, 420px); }
body.sda .sda-reading__print figcaption { margin-top: .9rem; }
/* `:not(.sda-eyebrow)` is load-bearing, not tidiness: this selector is (0,2,2)
   and .sda-eyebrow is (0,1,0), so without it the band's eyebrow would lose its
   tracked Hanken and its verdigris to a serif body rule. */
body.sda .sda-reading__copy p:not(.sda-eyebrow) { max-width: 46ch; margin: 1.2rem 0 0;
  font-family: var(--sda-serif); color: var(--sda-ink-soft); }
body.sda .sda-reading__copy .sda-btn { margin-top: 1.9rem; }

@media (max-width: 850px) {
  body.sda .sda-stones-open__spread, body.sda .sda-reading { grid-template-columns: minmax(0, 1fr); }
  body.sda .sda-walk { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  body.sda .sda-stones-open h1 { max-width: none; }
}
/* The pair stacks before the prints get small enough to stop being documents:
   two 250px slabs side by side is a thumbnail of a ruler. */
@media (max-width: 700px) {
  body.sda .sda-slab-pair__prints { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 560px) {
  body.sda .sda-walk { grid-template-columns: minmax(0, 1fr); }
  /* Two columns and two rows: the plate spans both, the name sits over its own
     count. A third column at this width would put a nine-character count
     against the right edge and squeeze the name to nothing. */
  body.sda .sda-guide__row { grid-template-columns: 88px minmax(0, 1fr); gap: 1rem; }
  body.sda .sda-guide__plate { width: 88px; grid-row: span 2; }
  body.sda .sda-guide__name { grid-column: 2; grid-row: 1; }
  body.sda .sda-guide__count { grid-column: 2; grid-row: 2; }
}

/* The slow-submit wait overlay (slow_submit.js). Invoice creation is a 3-10
   second QuickBooks round-trip, and the first booth cart got triple-tapped by
   people who read silence as failure. The outer .sda-wait deliberately has NO
   display rule: it carries the `hidden` attribute, and any display property
   here would beat the attribute and leave an invisible layer eating every tap.
   The flex column lives on __inner. */
.sda-wait { position: fixed; inset: 0; z-index: 60; background: color-mix(in srgb, var(--sda-night) 94%, transparent); backdrop-filter: blur(4px); }
.sda-wait__inner { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; gap: 1.1rem; padding: 0 2rem; text-align: center; }
.sda-wait__spinner { width: 2.4rem; height: 2.4rem; border-radius: 50%; border: 3px solid color-mix(in srgb, var(--sda-ink) 30%, transparent); border-top-color: var(--sda-copper); animation: sda-wait-spin .9s linear infinite; }
.sda-wait h2 { margin: 0; font: 600 var(--sda-h3)/1.2 var(--sda-serif); color: var(--sda-ink); }
.sda-wait p { max-width: 44ch; margin: 0; font-family: var(--sda-serif); color: var(--sda-ink-soft); }
@keyframes sda-wait-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .sda-wait__spinner { animation-duration: 2.5s; } }
