/* ───────────────────────────────────────────────
   styles.css — Sello de Cata (cupping-seal waitlist)
   Cascade layers per modern-web-guidance: reset, tokens, a11y, components.
   Palette: traditional coffee (umber/gold/cream/ink) — chosen after a
   4-persona focus group over 3 shortlisted concepts; see README.
   ─────────────────────────────────────────────── */
@layer reset, tokens, a11y, components;

@layer reset {
  :where(*, *::before, *::after) { box-sizing: inherit; margin: 0; }
  :where(html) { box-sizing: border-box; -webkit-text-size-adjust: 100%; }
  :where(body) { min-height: 100svh; line-height: 1.5; -webkit-font-smoothing: antialiased; }
  :where(img, picture, svg, canvas, video) { display: block; max-width: 100%; }
  :where(input, button, textarea, select) { font: inherit; color: inherit; }
  :where(button) { cursor: pointer; }
  :where(ul, ol) { padding: 0; margin: 0; list-style: none; }
  :where(a) { color: inherit; text-decoration: none; }
  :where(h1, h2, h3, h4, p) { text-wrap: pretty; }
  :where(h1) { text-wrap: balance; }
}

@layer tokens {
  :root {
    --umber: #6b4423;
    --gold: #c8932a;
    --cream: #f3ead9;
    --ink: #1a1512;
    /* The focus ring is a darker amber than the palette gold: #c8932a measures
       2.29:1 on cream, under the 3:1 minimum for a focus indicator. #a8741f
       measures 3.39:1 on cream and 4.05:1 on white while still reading amber.
       Gold itself stays the shader's highlight only. */
    --focus-ring: #a8741f;
    --umber-hover: #55351b;   /* primary button hover, per DESIGN.md */
    --success: #3f7d3a;       /* form status only, never decorative */
    --error: #b3261e;
    --warning: #8a5a1a;
    --font-mono: 'Courier Prime', 'Courier New', monospace;
    --tracking-loud: 0.09em;   /* badges, eyebrows, form-id: the shouty micro-labels */
    --tracking-quiet: 0.05em;  /* field labels, score labels: subordinate to the above */
  }
}

@layer a11y {
  :where(.visually-hidden) {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
  }
  :where(a, button, input, select, [tabindex]):focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 3px;
    border-radius: 2px;
  }
  .skip:not(:focus) { position: absolute; left: -9999px; }
  .skip:focus {
    position: fixed; top: 1rem; left: 1rem; z-index: 20;
    background: var(--ink); color: var(--cream);
    padding: 0.6rem 1rem; border-radius: 6px;
    font: 0.85rem 'Courier Prime', 'Courier New', monospace;
  }
  @media (prefers-reduced-motion: reduce) {
    [data-decorative-motion] { animation: none !important; }
  }
}

@layer components {
  html, body { height: 100%; }
  body {
    font-family: var(--font-mono);
    background: var(--cream);
    color: var(--ink);
  }

  .sheet {
    max-width: 68rem;
    margin: 0 auto;
    padding: clamp(1.25rem, 2vw + 1rem, 3rem);
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
  }

  .sheet > main {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
  }

  .sheet-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
  }

  /* The wordmark is the home link. It keeps the brand's look — ink, bold,
     uppercase — rather than the umber-and-dashed treatment the other links get,
     but it borrows their underline grammar on hover so it still reads as
     clickable. The border is always present (transparent at rest) so hovering
     cannot shift the header by a pixel. */
  .wordmark {
    display: inline-block;
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 1.15rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--ink);
    border-bottom: 1px dashed transparent;
    padding-bottom: 0.1em;
  }
  .wordmark:hover { border-bottom-color: currentColor; }
  /* The page's dashed-underline grammar is 1px everywhere: .foot-link and
     .legal > summary are the links, and role is carried by colour and weight
     (umber + bold vs ink + regular), not by dash thickness. */
  /* Supporting hint copy, not a pending-value marker. 0.6 ink over cream
     measures ~4.46:1 — a hair under WCAG AA 4.5:1 for body text. Known, and
     left as-is rather than changed in passing; the footer's removed status
     line used 0.65 (~5.2:1) for the same weight. */
  .placeholder-note {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    opacity: 0.68;          /* 5.79:1 on cream; 0.6 measured 4.46:1, under AA */
    line-height: 1.6;
  }

  .lang-toggle {
    background: transparent;
    border: 1px solid var(--ink);
    color: var(--ink);
    border-radius: 999px;
    padding: 0.5rem 1rem;
    min-height: 44px;
    font-family: var(--font-mono);
    font-size: 0.8rem;
    letter-spacing: var(--tracking-quiet);
  }
  .lang-toggle:hover { background: rgba(26,21,18,0.06); }
  .lang-toggle [data-lang-code] { opacity: 0.4; }
  .lang-toggle [data-lang-code].is-active { opacity: 1; font-weight: 700; }
  .lang-toggle .lang-sep { opacity: 0.4; margin: 0 0.3em; }

  .form-id {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    letter-spacing: var(--tracking-loud);
    text-transform: uppercase;
    color: var(--umber);
    border-top: 1px dashed var(--ink);
    border-bottom: 1px dashed var(--ink);
    padding: 0.5rem 0;
  }

  .cupping-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: start;
    gap: clamp(1.25rem, 3vw, 3rem);
  }

  .cupping-col--left {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
  }
  .cupping-label {
    font-family: var(--font-mono);
    display: grid;
    grid-template-columns: max-content 1fr;
    column-gap: 1.25rem;
    row-gap: 0.6rem;
    align-items: baseline;
    text-align: left;
    width: 100%;
    max-width: 24rem;
  }
  .cupping-label__row { display: contents; }
  .cupping-label__row dt {
    text-transform: uppercase;
    font-size: 0.75rem;
    letter-spacing: var(--tracking-quiet);
    color: var(--ink);
    opacity: 0.7;
    white-space: nowrap;
  }
  .cupping-label__row dd {
    font-weight: 700;
    font-size: 0.95rem;
    font-variant-numeric: tabular-nums;
    color: var(--umber);
    text-align: left;
  }

  .seal-col { display: flex; justify-content: center; }

  .seal {
    position: relative;
    width: clamp(200px, 30vw, 360px);
    aspect-ratio: 1;
    border-radius: 50%;
    overflow: hidden;
    border: 6px solid var(--ink);
    box-shadow: 0 0 0 3px var(--cream) inset, 0 12px 28px rgba(26,21,18,0.25);
    background: var(--umber);
  }
  .seal canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
  }
  .seal-ring {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    color: var(--cream);
    pointer-events: none;
    animation: seal-spin 40s linear infinite;
  }
  @keyframes seal-spin { to { transform: rotate(360deg); } }

  .eyebrow {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    letter-spacing: var(--tracking-loud);
    text-transform: uppercase;
    color: var(--umber);
  }

  .headline {
    font-family: var(--font-mono);
    font-weight: 700;
    /* Sized for a full keyword line, not for a two-word concept name: the
       typewriter face is wide, so a descriptive H1 needs a smaller ceiling to
       stay at two or three lines in this column. */
    font-size: clamp(1.25rem, 0.95rem + 1.1vw, 1.75rem);
    line-height: 1.2;
    letter-spacing: -0.01em;
    margin-top: 0.35rem;
  }

  .lede {
    font-size: clamp(1rem, 0.9rem + 0.3vw, 1.1rem);
    line-height: 1.5;
    max-width: 42ch;
    opacity: 0.85;
  }

  /* Colour hierarchy: a section heading is INK (the primary text colour, same
     as the h1), while everything subordinate to it — row titles, field labels,
     links, the lot label values — is UMBER. Before this, the section heading and
     its row titles were the same umber and the block read as one flat level. */
  h2.eyebrow { color: var(--ink); }

  .benefits {
    border-top: 1px dashed var(--ink);
    padding-top: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }
  .benefits-list {
    display: flex;
    flex-direction: column;
  }
  .benefits-item {
    border-bottom: 1px dashed rgba(26,21,18,0.25);
  }
  .benefits-item:last-child { border-bottom: none; }
  .benefits-item summary {
    font-family: var(--font-mono);
    font-weight: 700;
    text-transform: uppercase;
    font-size: 0.8rem;
    letter-spacing: var(--tracking-quiet);
    color: var(--umber);
    padding: 0.85rem 0;
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
  }
  .benefits-item summary::-webkit-details-marker { display: none; }
  .benefits-item summary::after {
    content: "+";
    font-weight: 700;
    font-size: 1.25em;     /* same rule as .legal > summary::after */
    color: var(--umber);
    flex-shrink: 0;
  }
  /* The typing caret: a umber block the width of a narrow glyph, blinking in
     hard steps so it reads as a terminal cursor rather than a fade. aria-hidden
     because it is decoration, and only ever in the DOM mid-animation. */
  .tw-caret {
    display: inline-block;
    width: 0.55ch;
    height: 1em;
    margin-left: 0.12ch;
    vertical-align: -0.14em;
    background: var(--umber);
    animation: tw-blink 1.06s steps(1, end) infinite;
  }
  @keyframes tw-blink { 50% { opacity: 0; } }
  @media (prefers-reduced-motion: reduce) { .tw-caret { animation: none; } }

  .benefits-item[open] summary::after { content: "–"; }
  .benefits-item summary:hover { background: rgba(26, 21, 18, 0.06); }
  .benefits-item summary:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
  .benefits-item p {
    font-size: 0.92rem;
    line-height: 1.55;
    opacity: 0.85;
    max-width: 52ch;
    padding-bottom: 0.9rem;
  }

  /* The rule belongs to the section, not to the form: the form is capped at
     34rem for line length, and a border on it would render a 544px dash while
     every other section rule spans the sheet's 996px. .form-block is a plain
     full-width wrapper that exists only to carry the rule at the same length
     as .benefits / .next-steps / .sheet-foot. */
  .form-block {
    border-top: 1px dashed var(--ink);
    padding-top: 1.5rem;   /* same 1.5rem as .benefits / .next-steps */
  }
  .cupping-form {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    max-width: 34rem;
    /* Left-aligned on the sheet's content edge, like .benefits and .next-steps
       above it. The section is balanced vertically, not horizontally. */
  }
  .cupping-form label {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: var(--tracking-quiet);
    color: var(--umber);
  }
  /* The form band's title is a real h2.eyebrow like the two above it, so it
     inherits the title treatment (0.8rem, loud tracking, ink) with no rule of
     its own. The email field keeps a .visually-hidden <label> so the control
     still has a name for assistive tech that matches the field, while the
     visible line is the invitation. */
  .form-row { display: flex; gap: 0.6rem; flex-wrap: wrap; }
  input[type="email"] {
    flex: 1 1 14rem;
    min-height: 48px;
    padding: 0 1rem;
    border-radius: 6px;
    border: 1px solid rgba(26,21,18,0.5);   /* 3.44:1 on white; 0.3 measured 1.96:1 */
    background: #fff;
    color: var(--ink);
  }
  input[type="email"]:user-invalid { border-color: var(--error); }
  select {
    min-height: 48px;
    padding: 0 1rem;
    border-radius: 6px;
    border: 1px solid rgba(26,21,18,0.5);   /* same boundary contrast as the input */
    background: #fff;
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 1rem;
    max-width: 22rem;
  }
  select:invalid { color: rgba(26,21,18,0.65); }   /* 5.61:1 on white; 0.55 measured 4.03:1 */
  select option { color: var(--ink); }              /* no UA black inside the palette */
  button[type="submit"] {
    min-height: 48px;
    padding: 0 1.5rem;
    border-radius: 6px;
    border: none;
    background: var(--umber);
    color: var(--cream);
    font-weight: 600;
  }
  button[type="submit"]:hover { background: var(--umber-hover); }

  /* The status line only exists once there is a message. Left in the flow while
     empty it added ~25px of invisible space under the privacy link, which made
     the form section read as bottom-heavy between its two rules. */
  [data-form-status]:empty { display: none; }
  [data-form-status] {
    font-family: var(--font-mono);
    font-size: 0.78rem;
    color: var(--umber);
  }
  [data-form-status][data-state="placeholder"] { color: var(--warning); }
  [data-form-status][data-state="error"] { color: var(--error); }
  [data-form-status][data-state="success"] { color: var(--success); }

  /* sheet-foot: the tear-off stub that closes the form. Same dashed section
     rule as .benefits/.cupping-form above it, so the sheet ends the way every
     other section breaks, and both channels are real links (mailto, profile)
     with the same dashed underline grammar. No new tokens, no shadow, no card
     surface. Earlier revisions opened with a form-number stub line echoing
     .form-id and closed with a right-aligned "not selling yet" status line;
     both restated something the page already registers, so the stub is the
     dashed rule plus .foot-channels and nothing else. */
  .sheet-foot {
    border-top: 1px dashed var(--ink);
    padding-top: 1.5rem;   /* same 1.5rem as every other dashed section */
  }
  /* Channel rows: an inline stroke glyph plus the value, umber for both so the
     icon and the link read as one mark. The bilingual channel name lives in a
     .visually-hidden span — the icon is aria-hidden decoration and is never the
     only label. */
  .foot-channel {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.45em;
    font-size: 0.8rem;
    color: var(--umber);
  }
  /* Hand-drawn 24x24 stroke glyphs: no icon font, no third-party icon set, no
     new runtime dependency. They inherit currentColor, so the umber/ink channel
     distinction carries into the icon. The radii inside these two glyphs are
     the source marks' own geometry (an envelope, Instagram's rounded square),
     not a third control radius — these are drawings, not controls. */
  .foot-icon {
    flex: 0 0 auto;
    width: 1.05em;
    height: 1.05em;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  .foot-channels {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
  }
  .foot-link {
    font-weight: 700;
    color: var(--umber);
    border-bottom: 1px dashed currentColor;
    padding-bottom: 0.1em;
  }
  .foot-link:hover { background: rgba(26,21,18,0.06); }

  /* next-steps / consent / legal — the closing argument and the
     fine print. Same dashed section rule and mono grammar as .benefits; no new
     tokens, no card surfaces, no shadow. */
  .next-steps {
    border-top: 1px dashed var(--ink);
    padding-top: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;             /* same gap as .benefits */
  }
  .next-steps-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    list-style: none;
    counter-reset: step;
    font-size: 0.92rem;
    line-height: 1.55;
    opacity: 0.85;
    max-width: 52ch;
  }
  .next-steps-list li { display: flex; gap: 0.7em; }
  .next-steps-list li::before {
    counter-increment: step;
    content: counter(step) ".";
    flex: 0 0 auto;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--umber);
  }
  /* Consent row and the layered notice under it. The checkbox must start
     unticked and the form must refuse to submit without it (RGPD/LSSI),
     so this is a control, not body copy: sentence case, full-strength ink. */
  .cupping-form .consent {
    display: flex;
    gap: 0.65rem;
    align-items: flex-start;
    text-transform: none;
    letter-spacing: normal;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--ink);
    cursor: pointer;
  }
  .consent input[type="checkbox"] {
    flex: 0 0 auto;
    width: 1.15rem;
    height: 1.15rem;
    margin: 0.1rem 0 0;
    accent-color: var(--umber);
  }
  /* The fine print is one link line under the consent row, not a section:
     "Política de privacidad" opens the policy in place. It exists for the
     visitor who wants it (and for the layered notice the consent row points
     to) and for nothing else — no rule, no label, no paragraph of legal
     chrome sitting on the page. */
  .legal > summary {
    width: fit-content;
    font-family: var(--font-mono);
    font-weight: 700;       /* every link on the page: umber, 1px dashed, bold */
    font-size: 0.75rem;
    color: var(--umber);
    border-bottom: 1px dashed currentColor;
    padding-bottom: 0.1em;
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: baseline;
    gap: 0.5em;
  }
  .legal > summary::-webkit-details-marker { display: none; }
  .legal > summary::after {
    content: "+";
    font-weight: 700;
    font-size: 1.25em;     /* same rule as .benefits-item summary::after */
    line-height: 1;
  }
  .legal[open] > summary::after { content: "–"; }
  .legal > summary:hover { background: rgba(26, 21, 18, 0.06); }
  .legal > summary:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
  .legal-body {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding-top: 0.85rem;
  }
  .legal-list {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    column-gap: 1rem;
    row-gap: 0.35rem;
    font-size: 0.75rem;
    line-height: 1.6;
  }
  .legal-row { display: contents; }
  /* Same label/value weighting as .cupping-label: dim label, full value. */
  .legal-list dd { max-width: 80ch; opacity: 0.85; }
  .legal-intro { font-size: 0.75rem; opacity: 0.85; max-width: 60ch; }
  .legal-list dt {
    text-transform: uppercase;
    letter-spacing: var(--tracking-quiet);
    opacity: 0.7;          /* matches .cupping-label__row dt */
    white-space: nowrap;
  }

  @media (max-width: 780px) {
    .cupping-grid { grid-template-columns: 1fr; text-align: center; }
    .cupping-col--right { order: -1; }
    .benefits { text-align: left; }
    .form-row { flex-direction: column; align-items: stretch; }
    .form-row input[type="email"] { flex: 0 0 auto; }
    .form-row select { max-width: none; width: 100%; }
    /* The header wraps here: the toggle lands on its own line and must hold
       the right edge, the one the badge above it holds. */
    .lang-toggle { margin-left: auto; }
    .legal-list { grid-template-columns: 1fr; row-gap: 0.15rem; }
    .legal-list dd { margin-bottom: 0.5rem; }
  }
}
