/*
 * luthier.css — WP-C1, contract 5 (spec §11, brand doc docs/standards/brand-luthier.md).
 *
 * The public reading path's only stylesheet. Light-first; dark is a peer, not an
 * override afterthought. Tokens are named for the instruments' own materials.
 *
 * Font binaries live in static/fonts/ and are NOT in this repo yet — see
 * static/fonts/README.md and brand doc §3.4 for the subsetting procedure and the
 * open ≤ 80 KB payload measurement. The @font-face blocks below name the files
 * that build step must produce.
 *
 * Preload, set in the document head by the layout renderer (WP-C2), covers ONLY
 * the two LCP-path faces: fraunces-latin.woff2 and newsreader-latin.woff2.
 * Atkinson is never preloaded (brand doc §3.2).
 */

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

/* Soundboard — light (default) */
:root {
  --ink:       #17141A;
  --ink-soft:  #4A434F;
  --surface:   #F3F1F4;
  --surface-2: #E7E3EC;
  --rosewood:  #6E2436;
  --brass:     #7C5F14;
  --rule:      #CFC9D6;

  /* Type roles — metric-compatible fallbacks (brand doc §3.3). */
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-body:    "Newsreader", "Iowan Old Style", Palatino, Georgia, serif;
  --font-util:    "Atkinson Hyperlegible Next", "Helvetica Neue", Arial, system-ui, sans-serif;

  /* Fluid scale, 1.25 ratio (spec §11.3). */
  --step--1: 0.833rem;
  --step-0:  1.0625rem;
  --step-1:  1.33rem;
  --step-2:  1.66rem;
  --step-3:  clamp(2rem, 1.6rem + 1.6vw, 2.9rem);

  /* Measures. */
  --measure-prose:    34rem;
  --measure-register: 56rem;
  --measure-page:     64rem;

  /* Purfling — the one divider and the one photo frame (spec §11.4). A stack of
     hairlines dark / light / dark, expressed as a layered box-shadow so it can
     edge any element. --rule is decorative only and is excluded from the
     contrast gate (brand doc §2.1). */
  --purfling: 0 0 0 1px var(--ink), 0 0 0 2px var(--surface), 0 0 0 3px var(--rule);
}

/* Workshop — dark */
@media (prefers-color-scheme: dark) {
  :root {
    --ink:       #EDE9F1;
    --ink-soft:  #B3ABBD;
    --surface:   #16131A;
    --surface-2: #1F1B26;
    --rosewood:  #E4899B;
    --brass:     #D6B25C;
    --rule:      #322C3B;
  }
}

/* ------------------------------------------------------------- @font-face -- */
/*
 * latin + latin-ext split. Anything outside both ranges falls to the system
 * face in the stack rather than a tofu box (spec §11.3). No italic ships.
 * Atkinson bold is loaded only by /submit/ and /curator/* via their own
 * stylesheet, outside the public budget.
 */

@font-face {
  font-family: "Fraunces";
  src: url("/fonts/fraunces-latin.woff2") format("woff2");
  font-weight: 340 620;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Fraunces";
  src: url("/fonts/fraunces-latinext.woff2") format("woff2");
  font-weight: 340 620;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Newsreader";
  src: url("/fonts/newsreader-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Newsreader";
  src: url("/fonts/newsreader-latinext.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url("/fonts/atkinson-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url("/fonts/atkinson-latinext.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ------------------------------------------------------------------- base -- */

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

html {
  color-scheme: light dark;
}

body {
  margin: 0;
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-text-size-adjust: 100%;
  text-rendering: optimizeLegibility;
}

main {
  max-width: var(--measure-page);
  margin-inline: auto;
  padding: clamp(1rem, 0.5rem + 2vw, 2.5rem);
}

/* Prose blocks (biography, owner notes) hold the narrow measure. */
.prose {
  max-width: var(--measure-prose);
}
.prose p {
  margin: 0 0 1em;
}

.register {
  max-width: var(--measure-register);
}
/* The register is an ordered list (WP-C3) — the count is meaningful to a screen
   reader — but the catalogue numeral is the visible index, so the list marker
   is suppressed. No new class token: scoped under the existing .register. */
.register ol {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* ----------------------------------------------------------- typography -- */

h1,
h2 {
  font-family: var(--font-display);
  font-weight: 560;
  line-height: 1.12;
  margin: 0 0 0.5em;
  font-variation-settings: "opsz" 40;
}

h1 {
  font-size: var(--step-3);
}
h2 {
  font-size: var(--step-2);
}

/* WONK is spent only above 2rem (spec §11.3). */
h1,
.catalogue-numeral {
  font-variation-settings: "opsz" 44, "WONK" 1;
}

h3 {
  font-family: var(--font-util);
  font-size: var(--step-1);
  margin: 2rem 0 0.5em;
}

/* Eyebrows and small-caps labels — short only; --brass margin is thin in light
   mode (brand doc §2.1). */
.eyebrow,
.label {
  font-family: var(--font-util);
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--brass);
}

.catalogue-numeral {
  font-family: var(--font-display);
  color: var(--rosewood);
  font-variant-numeric: tabular-nums lining-nums;
}

a {
  color: var(--rosewood);
  text-underline-offset: 0.12em;
}
a:hover {
  text-decoration-thickness: 2px;
}

/* Focus is one of the two things allowed to move (spec §11.4). Uses --rosewood,
   never --rule. */
:where(a, button, input, textarea, select, summary):focus-visible {
  outline: 2px solid var(--rosewood);
  outline-offset: 2px;
  border-radius: 1px;
}

/* Utility surfaces — forms, captions, the curator UI shell. */
.util {
  font-family: var(--font-util);
}
figcaption,
.caption {
  font-family: var(--font-util);
  font-size: var(--step--1);
  color: var(--ink-soft);
}

/* --------------------------------------------------------------- purfling -- */
/*
 * The 3-line stack is the ONLY divider and the ONLY photo frame. Nothing else
 * draws a border.
 */

.purfling-rule {
  border: 0;
  height: 3px;
  margin: 2.5rem 0;
  background: linear-gradient(
    var(--ink) 0 1px,
    var(--surface) 1px 2px,
    var(--rule) 2px 3px
  );
}

.photo-frame {
  padding: 3px;
  background: var(--surface);
  box-shadow: var(--purfling);
}
.photo-frame img {
  display: block;
  max-width: 100%;
  height: auto;
}

/* ---------------------------------------------------------------- rosette -- */
/*
 * The inline rosette SVG (static/rosette.svg). One animation: the rings draw in
 * from the outside over 700 ms, once, on first load only. The renderer adds
 * .rosette--draw on the first main-page render and never on navigation.
 */

.rosette {
  display: block;
  width: clamp(8rem, 6rem + 12vw, 14rem);
  height: auto;
  margin: 0 auto 2rem;
  color: var(--ink);
}
.rosette .rosette__light {
  color: var(--surface);
}
.rosette .rosette__numeral {
  fill: var(--rosewood);
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums lining-nums;
}

/* Small reprise on owner pages. */
.rosette--small {
  width: clamp(4.5rem, 3.5rem + 6vw, 7rem);
  margin-bottom: 1.5rem;
}

@media (prefers-reduced-motion: no-preference) {
  .rosette--draw .rosette__ring {
    stroke-dasharray: var(--ring-len, 1000);
    stroke-dashoffset: var(--ring-len, 1000);
    animation: rosette-draw 700ms ease-out forwards;
  }
  /* Three purfling bands, three hairlines each; outer band draws first. */
  .rosette--draw .rosette__ring:nth-of-type(-n + 3) { animation-delay: 0ms; }
  .rosette--draw .rosette__ring:nth-of-type(n + 4):nth-of-type(-n + 6) { animation-delay: 140ms; }
  .rosette--draw .rosette__ring:nth-of-type(n + 7) { animation-delay: 280ms; }
}

@keyframes rosette-draw {
  to {
    stroke-dashoffset: 0;
  }
}

/* Belt-and-braces: never animate under reduced-motion, even if a delay lands
   mid-run on load. */
@media (prefers-reduced-motion: reduce) {
  .rosette--draw .rosette__ring {
    animation: none;
    stroke-dashoffset: 0;
  }
}

/* ------------------------------------------------------------ skip link -- */

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--surface);
  color: var(--rosewood);
  padding: 0.5rem 1rem;
  font-family: var(--font-util);
}
.skip-link:focus {
  left: 0;
}

/* -------------------------------------------------- submission form (D2) -- */
/*
 * The whole submission form and its confirmation live under .submit-page. The
 * form is the widest utility surface on the site — Atkinson throughout, one
 * column, generous target sizes. No new colour tokens: every value below is an
 * existing token so the arithmetic contrast gate still covers it.
 */

.submit-page {
  max-width: var(--measure-prose);
  font-family: var(--font-util);
}

.submit-page .field {
  margin: 0 0 1.75rem;
}

.submit-page label {
  display: block;
  font-family: var(--font-util);
  margin-bottom: 0.35rem;
}

.submit-page .req {
  color: var(--brass);
  text-transform: uppercase;
  font-size: var(--step--1);
  letter-spacing: 0.06em;
}

.submit-page .field-hint {
  font-family: var(--font-util);
  font-size: var(--step--1);
  color: var(--ink-soft);
  margin: 0 0 0.5rem;
}

.submit-page input[type="text"],
.submit-page input[type="email"],
.submit-page input[type="url"],
.submit-page input[type="file"],
.submit-page textarea,
.submit-page select {
  display: block;
  width: 100%;
  max-width: 100%;
  font: inherit;
  font-family: var(--font-util);
  color: var(--ink);
  background: var(--surface-2);
  padding: 0.6rem 0.7rem;
}

.submit-page textarea {
  line-height: 1.5;
  resize: vertical;
}

.submit-page button[type="submit"] {
  font: inherit;
  font-family: var(--font-util);
  color: var(--surface);
  background: var(--rosewood);
  padding: 0.7rem 1.4rem;
  cursor: pointer;
}

/* Inline and summary errors — --rosewood on the page surface is a gate-proven
   pairing. Errors carry text ("There is a problem", the message), never colour
   alone, so 1.4.1 is met. */
.submit-page .error-summary {
  margin: 0 0 2rem;
  padding: 1rem 1.25rem;
  background: var(--surface-2);
  box-shadow: var(--purfling);
}
.submit-page .error-summary h2 {
  font-family: var(--font-util);
  font-size: var(--step-1);
  margin-top: 0;
  color: var(--rosewood);
}
.submit-page .error-summary a {
  color: var(--rosewood);
}

.submit-page .field-error,
.submit-page .form-error {
  font-family: var(--font-util);
  color: var(--rosewood);
  margin: 0.4rem 0 0;
}
.submit-page .field-error span {
  display: block;
}
.submit-page .form-error {
  margin: 0 0 1.5rem;
}

/*
 * The honeypot (spec §7.2). A real, focusable-by-nobody input moved out of view
 * geometrically — NOT display:none / visibility:hidden, which some bots detect
 * and skip. aria-hidden + tabindex="-1" keep it away from assistive tech and the
 * tab order; this rule keeps it away from sighted users.
 */
.submit-page .hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
