/*
 * hallebrews.beer
 *
 * Ported from the Claiden design system (claiden-android/.interface-design/system.md).
 * Those decisions are made; this file applies them rather than re-deciding.
 *
 * Three rules from that system do the most work here, and are the easiest to
 * erode later:
 *
 *   1. The temperature relationship INVERTS between themes, and that is the
 *      signature. Light is warm paper with cool graphite ink; dark is a cool
 *      night surface carrying warm ink. Do not "correct" either theme to one
 *      temperature, and do not build one by shifting the other's lightness.
 *
 *   2. Colour means something or it is not used. Neutrals carry the whole
 *      interface. Orange is the identity hue — it marks the wordmark and the
 *      brew data (ABV), nothing else. It is deliberately ABSENT from buttons,
 *      links, navigation and selection. When everything interactive is the
 *      accent colour, the accent stops saying anything.
 *
 *   3. Depth is hairline borders. No shadows anywhere.
 *
 * inkTertiary is the same #918C8B in both themes, so counts read identically.
 * In dark, surface is LIGHTER than canvas while inputs stay darker.
 */

/* --------------------------------------------------------------- fonts --- */

/* The same files claiden-android bundles, subsetted. Manrope carries the
   wordmark only; a brand mark in a different face from the interface is
   ordinary practice. */

@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-500.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-600.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}

@font-face {
  font-family: "Manrope";
  src: url("/fonts/manrope-800.woff2") format("woff2");
  font-weight: 800;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("/fonts/mono-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("/fonts/mono-600.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}

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

:root {
  /* Light: warm paper, cool graphite ink. */
  --canvas: #f5f4f3;
  /* Same colour as channels, so the masthead fade can reach zero alpha. */
  --canvas-rgb: 245 244 243;
  /* Settles the cover into the surface beneath it. The illustration is bright,
     and on the cool night canvas it would otherwise be the loudest thing here. */
  --cover-scrim: rgb(245 244 243 / 0.12);
  --canvas-raised: #fdfcfb;
  --surface: #ffffff;
  --control-fill: #f1f0ef;

  --primary: #4a4a4c;
  --on-primary: #f1f0ef;

  --ink: #39393d;
  --ink-secondary: #5c5959;
  --ink-tertiary: #918c8b;
  --ink-muted: #a7a2a1;

  --border: #e4e3e2;
  --border-strong: #d3d2d1;
  --border-interactive: #a7a2a1;

  /* Identity. Wordmark and brew data only. */
  --orange: #ea580c;
  --orange-subtle: #ffedd5;
  --orange-border: #fdba74;

  /* Status. Available / Fermenting / Planning, per the label-pill recipe:
     on light the fill is palest and the text darkest. */
  --green: #268047;
  --green-subtle: #dcfce7;
  --green-border: #86efac;
  --amber: #95691c;
  --amber-subtle: #fef9c3;
  --amber-border: #fde047;
  --blue: #355dbd;
  --blue-subtle: #dbeafe;
  --blue-border: #93c5fd;

  /* Base unit 4px. No value off this scale. */
  --s1: 4px;
  --s2: 6px;
  --s3: 8px;
  --s4: 12px;
  --s5: 16px;
  --s6: 20px;
  --s7: 24px;
  --s8: 32px;

  /* Chips · base (cards, buttons) · dialogs. Nested: outer = inner + padding. */
  --r-chip: 4px;
  --r-base: 8px;
  --r-large: 12px;

  --wrap: 60rem;

  --sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --wordmark-face: "Manrope", var(--sans);
  --mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --emoji: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;

  /* Fast, felt, never watched. Never ease-in — it stalls the first frame. */
  --ease: cubic-bezier(0.23, 1, 0.32, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    /* Dark: cool night surface, warm ink. Surface is lighter than canvas. */
    --canvas: #1a1a1d;
    --canvas-rgb: 26 26 29;
    --cover-scrim: rgb(26 26 29 / 0.5);
    --canvas-raised: #232326;
    --surface: #28282b;
    --control-fill: #3f3f42;

    --primary: #e4e3e2;
    --on-primary: #2d2d31;

    --ink: #e4e3e2;
    --ink-secondary: #bdb8b7;
    --ink-tertiary: #918c8b; /* identical to light, deliberately */
    --ink-muted: #6b6867;

    --border: #3f3f42;
    --border-strong: #4a4a4c;
    --border-interactive: #6b6867;

    /* Identity and status shift CHARACTER on dark — a pale tint, not the light
       hue lightened. The fill takes the light theme's text tone, the border
       becomes the most saturated element, and the text is palest. */
    --orange: #fed7aa;
    --orange-subtle: #7c2d12;
    --orange-border: #ea580c;

    --green: #bbf7d0;
    --green-subtle: #14532d;
    --green-border: #16a34a;
    --amber: #fef08a;
    --amber-subtle: #713f12;
    --amber-border: #ca8a04;
    --blue: #bfdbfe;
    --blue-subtle: #35467d;
    --blue-border: #3f80eb;
  }
}

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

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
}

:where(a, button, label, [tabindex]):focus-visible {
  outline: 2px solid var(--border-interactive);
  outline-offset: 2px;
  border-radius: var(--r-chip);
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--s5);
}

/* ------------------------------------------------------------ masthead --- */

/*
 * Full-bleed, and it dissolves into the canvas rather than ending at an edge.
 * A bordered box would make the illustration an object the eye has to resolve;
 * faded, it reads as atmosphere and nothing jumps under the squint test.
 *
 * The fade stops must be the canvas colour at zero alpha, not `transparent` —
 * `transparent` is rgba(0,0,0,0) and blending toward it greys the midpoint.
 * That is what `--canvas-rgb` exists for.
 */
.masthead {
  padding-top: clamp(132px, 21vw, 232px);
  background:
    linear-gradient(
      to bottom,
      rgb(var(--canvas-rgb) / 0) 32%,
      rgb(var(--canvas-rgb) / 0.72) 72%,
      rgb(var(--canvas-rgb) / 1) 100%
    ),
    linear-gradient(var(--cover-scrim), var(--cover-scrim)),
    url("/cover.png") center 52% / cover no-repeat;
}

.masthead-text {
  padding-block: var(--s5) var(--s7);
}

/* Manrope ExtraBold, and the one place orange marks the product itself.
   Tracking tightens as the type grows; it is never loosened. */
.wordmark {
  margin: 0;
  font-family: var(--wordmark-face);
  font-weight: 800;
  font-size: clamp(30px, 7vw, 44px);
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: var(--orange);
}

.tagline {
  margin: var(--s3) 0 0;
  /* Wide enough that "pseudo-science" does not break across the hyphen. */
  max-width: 56ch;
  color: var(--ink-secondary);
  font-size: 14px;
  line-height: 1.45;
  text-wrap: pretty;
}

/* ------------------------------------------------------------- section --- */

.section-head {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  margin-bottom: var(--s4);
}

/* A label, not a heading. Weight carries it, not size. */
.section-head h2 {
  margin: 0;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.43;
  color: var(--ink);
}

.beers {
  padding-bottom: var(--s8);
}

/* ---------------------------------------------------------------- tabs --- */

.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s1);
  margin-bottom: var(--s5);
}

/* Selected state is control fill + interactive border + ink. NOT a hue —
   orange marks what a brew is, not where you are. */
.tab {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  min-height: 32px;
  padding: var(--s2) var(--s4);
  border: 1px solid transparent;
  border-radius: var(--r-base);
  color: var(--ink-secondary);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 160ms var(--ease), color 160ms var(--ease),
    border-color 160ms var(--ease);
}

/* Visually collapsed, still in the accessibility tree. */
.tab input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.tab .n {
  font-family: var(--mono);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-tertiary);
}

.tab:hover {
  background: var(--control-fill);
  color: var(--ink);
}

.tab:has(:checked) {
  background: var(--control-fill);
  border-color: var(--border-interactive);
  color: var(--ink);
}

.tab:has(:focus-visible) {
  outline: 2px solid var(--border-interactive);
  outline-offset: 2px;
}

/* -------------------------------------------------------------- filter --- */

.beers:has(#tab-Packaged:checked) .card:not([data-status="Packaged"]),
.beers:has(#tab-Fermenting:checked) .card:not([data-status="Fermenting"]),
.beers:has(#tab-Planning:checked) .card:not([data-status="Planning"]),
.beers:has(#tab-Empty:checked) .card:not([data-status="Empty"]) {
  display: none;
}

.empty {
  display: none;
  grid-column: 1 / -1;
  padding: var(--s8) 0;
  color: var(--ink-tertiary);
  font-size: 14px;
}

.beers:has(#tab-Packaged:checked) .empty[data-status="Packaged"],
.beers:has(#tab-Fermenting:checked) .empty[data-status="Fermenting"],
.beers:has(#tab-Planning:checked) .empty[data-status="Planning"],
.beers:has(#tab-Empty:checked) .empty[data-status="Empty"] {
  display: block;
}

/* --------------------------------------------------------------- cards --- */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
  gap: var(--s5);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Surface · 16px pad · 8px radius · 1px border · no shadow. */
.card-link {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  column-gap: var(--s4);
  row-gap: var(--s1);
  height: 100%;
  padding: var(--s5);
  border: 1px solid var(--border);
  border-radius: var(--r-base);
  background: var(--surface);
  text-decoration: none;
  transition: border-color 160ms var(--ease), background-color 160ms var(--ease),
    transform 120ms var(--ease);
}

.card-link:hover {
  border-color: var(--border-interactive);
}

.card-link:active {
  transform: scale(0.97);
}

.card-glyph {
  grid-row: 1 / 3;
  align-self: start;
  font-family: var(--emoji);
  font-size: 28px;
  line-height: 1.15;
}

.card-name {
  font-size: 16px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink);
  text-wrap: balance;
}

.card-meta {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  min-width: 0;
}

.card-style {
  flex: 1;
  min-width: 0;
  color: var(--ink-tertiary);
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Brew data keeps the identity hue, and any changing number gets the mono
   face for tabular figures. This is the only colour on a card. */
.abv {
  font-family: var(--mono);
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--orange);
}

/* -------------------------------------------------------------- badges --- */

.badge {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 var(--s3);
  border: 1px solid;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}

.badge[data-status="Packaged"] {
  background: var(--green-subtle);
  border-color: var(--green-border);
  color: var(--green);
}

.badge[data-status="Fermenting"] {
  background: var(--amber-subtle);
  border-color: var(--amber-border);
  color: var(--amber);
}

.badge[data-status="Planning"] {
  background: var(--blue-subtle);
  border-color: var(--blue-border);
  color: var(--blue);
}

/* Archive is absent, not a state worth a hue. */
.badge[data-status="Empty"] {
  background: var(--control-fill);
  border-color: var(--border);
  color: var(--ink-tertiary);
}

/* ---------------------------------------------------------- beer page --- */

.beer {
  padding-block: var(--s7) var(--s8);
  max-width: 42rem;
}

.back {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  color: var(--ink-secondary);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
}

.back:hover {
  color: var(--ink);
}

.beer-head {
  display: flex;
  align-items: flex-start;
  gap: var(--s5);
  margin-top: var(--s5);
}

.beer-glyph {
  font-family: var(--emoji);
  font-size: 44px;
  line-height: 1;
}

/* The one name this screen is about. */
.beer-name {
  margin: 0;
  font-size: 30px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: balance;
}

.beer-sub {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
  margin-top: var(--s3);
}

.chip {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 var(--s2);
  border: 1px solid var(--border);
  border-radius: var(--r-chip);
  background: var(--control-fill);
  color: var(--ink-secondary);
  font-size: 12px;
  font-weight: 500;
}

.chips {
  display: contents;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Card padding is 16px and children are 4px chips, so the card's 8px base
   radius keeps outer = inner + padding rather than repeating one radius. */
.card-block {
  margin-top: var(--s7);
  padding: var(--s5);
  border: 1px solid var(--border);
  border-radius: var(--r-base);
  background: var(--surface);
}

.facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s8);
  margin: 0;
}

.facts dt {
  margin: 0;
  color: var(--ink-tertiary);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.facts dd {
  margin: var(--s2) 0 0;
}

/* The metric this page is about. */
.facts .abv {
  font-size: 20px;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  margin-top: var(--s7);
  padding: 0 var(--s5);
  border: 1px solid transparent;
  border-radius: var(--r-base);
  background: var(--primary);
  color: var(--on-primary);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  transition: opacity 160ms var(--ease), transform 120ms var(--ease);
}

.button:hover {
  opacity: 0.88;
}

.button:active {
  transform: scale(0.97);
}

/* ---------------------------------------------------------------- notes --- */

.notes {
  color: var(--ink-secondary);
  font-size: 16px;
  line-height: 1.5;
  text-wrap: pretty;
}

.notes > :first-child {
  margin-top: 0;
}

.notes > :last-child {
  margin-bottom: 0;
}

.notes p {
  margin: 0 0 var(--s4);
}

.notes h2,
.notes h3,
.notes h4 {
  margin: var(--s7) 0 var(--s3);
  color: var(--ink);
  font-weight: 600;
}

.notes h2 {
  font-size: 20px;
  letter-spacing: -0.01em;
}

.notes h3 {
  font-size: 16px;
}

.notes h4 {
  font-size: 14px;
}

.notes ul,
.notes ol {
  margin: 0 0 var(--s4);
  padding-left: var(--s6);
}

.notes li {
  margin-bottom: var(--s1);
}

.notes li.todo {
  list-style: none;
  margin-left: calc(var(--s6) * -1);
}

.notes li.todo::before {
  content: "☐  ";
  color: var(--ink-muted);
}

.notes li.todo-done::before {
  content: "☑  ";
  color: var(--ink-tertiary);
}

.notes li.todo-done {
  color: var(--ink-muted);
}

/* Links are ink with an underline, not the identity hue. */
.notes a {
  color: var(--ink);
  text-decoration-color: var(--border-interactive);
  text-underline-offset: 0.15em;
}

.notes a:hover {
  text-decoration-color: var(--ink);
}

.notes code {
  padding: 0.1em 0.3em;
  border: 1px solid var(--border);
  border-radius: var(--r-chip);
  background: var(--canvas-raised);
  font-family: var(--mono);
  font-size: 0.85em;
}

.notes pre {
  margin: 0 0 var(--s4);
  padding: var(--s4);
  border: 1px solid var(--border);
  border-radius: var(--r-base);
  background: var(--canvas-raised);
  overflow-x: auto;
}

.notes pre code {
  padding: 0;
  border: 0;
  background: none;
}

.notes blockquote {
  margin: 0 0 var(--s4);
  padding-left: var(--s4);
  border-left: 2px solid var(--border-strong);
  color: var(--ink-tertiary);
}

.notes .callout {
  display: flex;
  gap: var(--s3);
  margin: 0 0 var(--s4);
  padding: var(--s4);
  border: 1px solid var(--border);
  border-radius: var(--r-base);
  background: var(--canvas-raised);
}

.notes .callout p {
  margin: 0;
}

.notes hr {
  margin: var(--s6) 0;
  border: 0;
  border-top: 1px solid var(--border);
}

/* --------------------------------------------------------------- footer --- */

.site-footer {
  padding-block: var(--s6) var(--s8);
  border-top: 1px solid var(--border);
}

.ig {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  color: var(--ink);
  font-size: 14px;
  font-weight: 500;
  text-decoration-color: var(--border-interactive);
  text-underline-offset: 0.15em;
}

.colophon {
  margin: var(--s1) 0 0;
  color: var(--ink-tertiary);
  font-size: 12px;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
  }

  .card-link:active,
  .button:active {
    transform: none;
  }
}
