/*
 * BuildBatch: one stylesheet for the whole site.
 *
 *   design-system/buildbatch/MASTER.md            the brand: colours, type, shape, states
 *   design-system/buildbatch/pages/calculator.md  how calculator pages apply it, and why
 *
 * Direction: "Workshop". A practical working toolkit: strong type, clearly
 * presented quantities, warm neutral surfaces, restrained lime accents, 6px
 * corners, thin borders, no shadows, no gradients, nothing decorative that moves.
 *
 * Mobile first: everything works at 320px and wider layouts are added on top.
 * Components only ever use the semantic tokens below, never raw colours, so the
 * palette lives in this block and nowhere else. Light only: there is no dark mode.
 */

/* Fonts are hosted here, not fetched from a third party. Licences: assets/fonts/OFL-*.txt */
@font-face {
  font-family: "Barlow Semi Condensed";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/barlow-semi-condensed-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Barlow Semi Condensed";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/barlow-semi-condensed-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* One variable file covers Work Sans 400 to 600. */
@font-face {
  font-family: "Work Sans";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/work-sans-400-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  color-scheme: light;

  /* Brand palette, by role. The names in brackets are the brand's names for them. */
  --color-primary: #202a2e; /* Graphite: headings, navigation, dark result surfaces */
  --color-on-primary: #ffffff;
  --color-accent: #d7f36b; /* Signal lime: the primary action and small brand accents */
  --color-on-accent: #202a2e; /* Graphite on lime, never white */
  --color-background: #f5f3ec; /* Limestone: the page */
  --color-card: #ffffff; /* Paper: forms and content */
  --color-foreground: #202a2e;
  --color-muted-foreground: #52605f; /* Slate: supporting text */
  --color-control-border: #74817b; /* Tool grey: input and select boundaries */
  --color-border: #d9ddd5; /* Light stone: decorative dividers only, never a control boundary */
  --color-link: #275b50; /* Deep green: underlined links on light surfaces */
  --color-warning-text: #8a4b10;
  --color-warning-tint: #fff3de;
  --color-destructive-text: #b42318;
  --color-destructive-tint: #fff1f0;

  /* States and supporting neutrals. Defined, not guessed: every pair is checked by tests/design/contrast.test.js */
  --color-primary-hover: #34424a;
  --color-primary-active: #12181b;
  --color-on-primary-muted: #c9d0cb; /* supporting text on graphite */
  --color-accent-hover: #c6e651;
  --color-accent-active: #b4d63b;
  --color-muted: #ece9df; /* a step darker than limestone: unit boxes, notices, hover fills */
  --color-muted-active: #d9ddd5;
  --color-link-hover: #202a2e;
  --color-disabled: #e6e8e1;
  --color-on-disabled: #52605f;
  --color-ring: #202a2e; /* keyboard focus on light surfaces */
  --color-ring-on-dark: #d7f36b; /* keyboard focus on graphite */

  /* Type: Barlow Semi Condensed 600 to 700 for the wordmark and short headings, Work Sans 400 to 600 for everything read */
  --font-heading: "Barlow Semi Condensed", "Arial Narrow", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: "Work Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.5rem;
  --text-2xl: 2rem;
  --text-3xl: 2.5rem;

  /* Space: 4 and 8 point rhythm */
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-smd: 0.75rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;
  --space-2xl: 3rem;
  --space-3xl: 4rem;

  /* Shape: about 6px corners, thin borders, no shadows */
  --radius: 6px;
  --border-thin: 1px;
  --border-control: 2px;

  /* Motion: state changes only. Short, and off entirely for anyone who asks for reduced motion. */
  --duration-state: 150ms;
  --duration-enter: 300ms;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --control-height: 3rem;
}

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

/* Author display rules must never beat the hidden attribute. */
[hidden] {
  display: none !important;
}

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

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.5;
  color: var(--color-foreground);
  background: var(--color-background);
}

/* Work Sans is loaded up to 600, so bold text asks for 600 rather than a synthesised 700. */
strong,
b {
  font-weight: 600;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 600;
  line-height: 1.15;
  text-wrap: balance;
}

h1 {
  margin-top: var(--space-lg);
  font-size: clamp(var(--text-2xl), 1.5rem + 2.2vw, var(--text-3xl));
  font-weight: 700;
}

p,
ul,
ol {
  margin: var(--space-smd) 0 0;
}

p {
  text-wrap: pretty;
}

a {
  color: var(--color-link);
  text-decoration: underline;
  text-underline-offset: 0.18em;
  transition: color var(--duration-state) var(--ease-out);
}

a:hover {
  color: var(--color-link-hover);
}

:focus-visible {
  outline: 3px solid var(--color-ring);
  outline-offset: 2px;
  border-radius: 4px;
}

a,
button,
input,
select,
label,
summary {
  touch-action: manipulation;
}

.icon {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
}

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.print-only {
  display: none;
}

.skip-link {
  position: absolute;
  left: var(--space-sm);
  top: -5rem;
  z-index: 100;
  padding: var(--space-sm) var(--space-md);
  border: var(--border-control) solid var(--color-primary);
  border-radius: var(--radius);
  background: var(--color-accent);
  color: var(--color-on-accent);
  font-weight: 600;
}

.skip-link:focus {
  top: var(--space-sm);
}

/* It is not inside the header, but it appears on top of it, so it takes the ring for graphite surfaces. */
.skip-link:focus-visible {
  outline-color: var(--color-ring-on-dark);
}

/* Page furniture */

.page {
  width: 100%;
  max-width: 72rem;
  margin: 0 auto;
  padding: 0 var(--space-md);
}

.site-header {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

/* Graphite surface: the focus ring switches to lime so it stays visible. */
.site-header :focus-visible {
  outline-color: var(--color-ring-on-dark);
}

.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0 var(--space-md);
  min-height: 3.5rem;
}

/* The wordmark: the name set in Barlow Semi Condensed 700, with a small stack of three blocks.
   The mark sits inside the home link and carries no meaning of its own. */
.site-header__name {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  min-height: 2.75rem;
  color: var(--color-on-primary);
  font-family: var(--font-heading);
  font-size: 1.375rem;
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
}

.site-header__name:hover {
  color: var(--color-on-primary);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.25em;
}

.site-header__mark {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  color: var(--color-accent);
}

.site-nav ul {
  display: flex;
  gap: var(--space-xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: 0 var(--space-sm);
  border-radius: var(--radius);
  color: var(--color-on-primary);
  font-size: var(--text-sm);
  font-weight: 500;
  text-decoration: none;
  transition: background-color var(--duration-state) var(--ease-out);
}

.site-nav a:hover {
  background: var(--color-primary-hover);
  color: var(--color-on-primary);
}

.site-nav a:active {
  background: var(--color-primary-active);
}

/* Where you are: said by weight and a lime underline, not by colour alone. */
.site-nav a[aria-current="page"] {
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--color-accent);
  text-decoration-thickness: 3px;
  text-underline-offset: 0.45em;
}

.site-footer {
  margin-top: var(--space-3xl);
  padding: var(--space-lg) 0 var(--space-2xl);
  border-top: var(--border-thin) solid var(--color-border);
  color: var(--color-muted-foreground);
  font-size: var(--text-sm);
}

/* The information pages. They wrap to one per line on a narrow screen, where each row is a 44px target. */
.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--space-lg);
  margin: 0 0 var(--space-md);
  padding: 0;
  list-style: none;
}

.site-footer__links a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-weight: 500;
}

/* A fact the owner has not supplied yet. Deliberately obvious: a launch blocker, not decoration. */
.placeholder {
  display: inline-block;
  padding: 0 var(--space-xs);
  border: var(--border-thin) dashed var(--color-warning-text);
  border-radius: 4px;
  background: var(--color-warning-tint);
  color: var(--color-warning-text);
  font-weight: 500;
}

.banner {
  display: flex;
  gap: var(--space-sm);
  margin-top: var(--space-md);
  padding: var(--space-smd) var(--space-md);
  border: var(--border-thin) solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-muted);
  font-size: var(--text-sm);
}

.banner .icon {
  margin-top: 0.125rem;
  color: var(--color-link);
}

.lead {
  max-width: 42rem;
}

.scope,
.meta {
  color: var(--color-muted-foreground);
  font-size: var(--text-sm);
}

.scope {
  max-width: 42rem;
}

.panel {
  margin: 0;
  padding: var(--space-md);
  border: var(--border-thin) solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-card);
}

.prose {
  max-width: 42rem;
  margin-top: var(--space-2xl);
}

.prose h2 {
  font-size: var(--text-xl);
}

.prose li {
  margin-top: var(--space-sm);
}

/* Home page: the tagline, three plain reasons, the calculators. Deliberately short. */

.hero {
  padding: var(--space-xl) 0 var(--space-lg);
}

.hero h1 {
  max-width: 18ch;
  margin-top: 0;
}

.hero__actions {
  margin-top: var(--space-lg);
}

.features,
.module-list {
  display: grid;
  gap: var(--space-md);
  margin-top: var(--space-lg);
  padding: 0;
  list-style: none;
}

.feature {
  display: flex;
  gap: var(--space-smd);
}

.feature .icon {
  width: 1.5rem;
  height: 1.5rem;
  margin-top: 0.125rem;
  color: var(--color-link);
}

.feature h3 {
  font-size: var(--text-lg);
}

.feature p {
  margin-top: var(--space-xs);
  color: var(--color-muted-foreground);
}

.section-title {
  margin-top: var(--space-2xl);
  font-size: var(--text-xl);
}

.module-card {
  position: relative;
  transition: border-color var(--duration-state) var(--ease-out);
}

.module-card h3 {
  font-size: var(--text-lg);
}

.module-card a {
  color: var(--color-primary);
  text-decoration: none;
}

/* The whole card is the link target, so it is an easy tap. */
.module-card a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
}

.module-card:has(a) {
  cursor: pointer;
}

.module-card:has(a):hover {
  border-color: var(--color-primary);
}

.module-card:has(a:focus-visible) {
  outline: 3px solid var(--color-ring);
  outline-offset: 2px;
}

.module-card a:focus-visible {
  outline: none;
}

.module-card__go {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  margin-top: var(--space-smd);
  color: var(--color-link);
  font-weight: 600;
}

.module-card--planned {
  border-style: dashed;
  border-color: var(--color-control-border);
  background: transparent;
  color: var(--color-muted-foreground);
}

/* Calculator layout */

.calculator {
  display: grid;
  gap: var(--space-lg);
  margin-top: var(--space-lg);
}

.calculator__form {
  display: grid;
  gap: var(--space-md);
  min-width: 0;
}

.calculator__results {
  min-width: 0;
}

.form-note {
  margin: 0;
  color: var(--color-muted-foreground);
  font-size: var(--text-sm);
}

/* Form sections and fields.
   Fieldsets carry no box of their own: a wrapping .panel draws it, so the legend behaves like a heading. */

fieldset {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

legend {
  display: block;
  width: 100%;
  padding: 0;
}

.section__legend,
.legend__heading {
  font-family: var(--font-heading);
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.15;
}

.field {
  margin-top: var(--space-md);
}

.field--group {
  margin-top: 0;
}

.field__label {
  display: block;
  font-weight: 500;
}

.field__hint {
  margin-top: 0.125rem;
  color: var(--color-muted-foreground);
  font-size: var(--text-sm);
}

.field__control {
  display: flex;
  align-items: stretch;
  margin-top: var(--space-sm);
}

.field__control--xs {
  max-width: 6rem;
}

.field__control--sm {
  max-width: 9rem;
}

.field__control--md {
  max-width: 14rem;
}

/* Input text stays at 16px or more, so phones do not zoom the page when a field is tapped. */
.field__input,
.field__select {
  width: 100%;
  min-width: 0;
  min-height: var(--control-height);
  padding: var(--space-smd);
  border: var(--border-thin) solid var(--color-control-border);
  border-radius: var(--radius);
  background: var(--color-card);
  color: var(--color-foreground);
  font: inherit;
  font-variant-numeric: tabular-nums;
  transition: border-color var(--duration-state) var(--ease-out);
}

.field__select {
  max-width: 14rem;
  cursor: pointer;
}

.field__input:hover,
.field__select:hover {
  border-color: var(--color-primary);
}

.field__input:focus-visible,
.field__select:focus-visible {
  border-color: var(--color-primary);
  border-radius: var(--radius);
}

.field__input:disabled,
.field__select:disabled {
  border-color: var(--color-control-border);
  background: var(--color-disabled);
  color: var(--color-on-disabled);
  cursor: not-allowed;
}

.field__input:has(+ .field__suffix) {
  border-right: 0;
  border-radius: var(--radius) 0 0 var(--radius);
}

/* An input and its unit are one control, so the focus ring goes round both. */
@supports selector(:has(*)) {
  .field__control:has(.field__input:focus-visible) {
    outline: 3px solid var(--color-ring);
    outline-offset: 2px;
    border-radius: var(--radius);
  }

  .field__control .field__input:focus-visible {
    outline: none;
  }

  .field__control:has(.field__input:focus-visible) .field__suffix {
    border-color: var(--color-primary);
  }
}

.field__suffix {
  display: flex;
  align-items: center;
  padding: 0 var(--space-smd);
  border: var(--border-thin) solid var(--color-control-border);
  border-left: 0;
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--color-muted);
  color: var(--color-muted-foreground);
  font-size: var(--text-sm);
  white-space: nowrap;
}

.field--error .field__input,
.field--error .field__input + .field__suffix {
  border-color: var(--color-destructive-text);
  box-shadow: inset 0 0 0 1px var(--color-destructive-text);
}

.field--error .field__input + .field__suffix {
  box-shadow:
    inset 0 1px 0 0 var(--color-destructive-text),
    inset 0 -1px 0 0 var(--color-destructive-text),
    inset -1px 0 0 0 var(--color-destructive-text);
}

/* Errors and warnings always carry an icon and words. Colour is never the only signal. */
.field__message {
  display: flex;
  gap: var(--space-sm);
  margin-top: var(--space-sm);
  font-size: var(--text-sm);
}

.field__message .icon {
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.125rem;
}

.field__message--error {
  color: var(--color-destructive-text);
  font-weight: 500;
}

.field__message--warning {
  padding: var(--space-sm) var(--space-smd);
  border-radius: var(--radius);
  background: var(--color-warning-tint);
  color: var(--color-warning-text);
}

.field-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  gap: 0 var(--space-md);
  align-items: start;
}

/* Fields side by side share their rows, so inputs line up even when one has a hint and its neighbour does not. */
@supports (grid-template-rows: subgrid) {
  .field-row > .field {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
  }

  .field-row > .field > .field__label {
    grid-row: 1;
    align-self: end;
  }

  .field-row > .field > .field__hint {
    grid-row: 2;
  }

  .field-row > .field > .field__control {
    grid-row: 3;
  }

  .field-row > .field > .field__message {
    grid-row: 4;
  }
}

.tag {
  display: inline-block;
  padding: 0 var(--space-sm);
  border-radius: 4px;
  background: var(--color-warning-tint);
  color: var(--color-warning-text);
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1.6;
  white-space: nowrap;
}

.checkbox-list {
  margin-top: var(--space-sm);
}

.checkbox {
  display: flex;
  align-items: center;
  gap: var(--space-smd);
  min-height: 2.75rem;
}

.checkbox input {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  margin: 0;
  accent-color: var(--color-primary);
  cursor: pointer;
}

.checkbox label {
  flex: 1;
  padding: var(--space-sm) 0;
  cursor: pointer;
}

/* Buttons. One lime action per view. Graphite for the next most important. Outline for the rest.
   Every state is a defined token, and lime always has a graphite edge so its shape shows on a light page. */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  min-height: var(--control-height);
  padding: var(--space-smd) var(--space-lg);
  border: var(--border-control) solid var(--color-primary);
  border-radius: var(--radius);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition:
    background-color var(--duration-state) var(--ease-out),
    border-color var(--duration-state) var(--ease-out),
    color var(--duration-state) var(--ease-out);
}

.button--accent {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.button--accent:hover {
  background: var(--color-accent-hover);
  color: var(--color-on-accent);
}

.button--accent:active {
  background: var(--color-accent-active);
}

.button--primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.button--primary:hover {
  border-color: var(--color-primary-hover);
  background: var(--color-primary-hover);
  color: var(--color-on-primary);
}

.button--primary:active {
  border-color: var(--color-primary-active);
  background: var(--color-primary-active);
}

.button--secondary {
  background: var(--color-card);
  color: var(--color-primary);
}

.button--secondary:hover {
  background: var(--color-muted);
}

.button--secondary:active {
  background: var(--color-muted-active);
}

.button--danger-link {
  min-height: 2.75rem;
  padding: var(--space-xs) var(--space-sm);
  border-color: transparent;
  background: none;
  color: var(--color-destructive-text);
  font-size: var(--text-sm);
}

.button--danger-link:hover,
.button--danger-link:active {
  border-color: var(--color-destructive-text);
  background: var(--color-destructive-tint);
}

.button:disabled,
.button[aria-disabled="true"] {
  border-color: var(--color-control-border);
  background: var(--color-disabled);
  color: var(--color-on-disabled);
  cursor: not-allowed;
}

.button--small {
  min-height: 2.75rem;
  padding: var(--space-sm) var(--space-md);
  font-size: var(--text-sm);
}

.button--wide {
  width: 100%;
}

a.button {
  text-decoration: none;
}

/* Repeater */

.repeater__item {
  margin-top: var(--space-md);
  padding: var(--space-xs) var(--space-md) var(--space-md);
  border: var(--border-thin) solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-background);
}

.repeater__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
}

.repeater__heading {
  font-size: var(--text-lg);
}

.repeater__actions {
  margin-top: var(--space-md);
}

/* Error summary */

.error-summary {
  padding: var(--space-md);
  border: var(--border-control) solid var(--color-destructive-text);
  border-radius: var(--radius);
  background: var(--color-destructive-tint);
}

.error-summary__title {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  color: var(--color-destructive-text);
  font-size: 1.375rem;
}

.error-summary__list {
  padding-left: var(--space-lg);
}

.error-summary__list li {
  margin-top: var(--space-sm);
}

.error-summary__list a {
  color: var(--color-destructive-text);
  font-weight: 500;
}

.error-summary__list a:hover {
  color: var(--color-foreground);
}

/* Results */

.results__heading {
  font-size: var(--text-2xl);
}

.results__heading:focus-visible {
  outline-offset: 4px;
}

.results__subheading {
  font-size: var(--text-xl);
}

.results__placeholder {
  color: var(--color-muted-foreground);
}

.results__placeholder ul {
  margin-top: var(--space-sm);
  padding-left: var(--space-lg);
}

/* "No estimate" when a calculation fails: a message in the answer's place, at full strength, not muted. */
.results__placeholder .notice {
  color: var(--color-foreground);
}

.results__placeholder .notice ul {
  padding-left: var(--space-md);
}

.results__placeholder li {
  margin-top: var(--space-xs);
}

.results__details > * {
  margin-top: var(--space-md);
}

.results__list {
  margin-top: var(--space-lg);
  padding-top: var(--space-lg);
  border-top: var(--border-thin) solid var(--color-border);
}

.results__footnote {
  margin-top: var(--space-lg);
  color: var(--color-muted-foreground);
  font-size: var(--text-sm);
}

/* The quantity to buy, on graphite with a lime edge: the one thing on the page that should be impossible to miss.
   The title, quantity and sentence are three elements styled as one dark block, so the markup did not have to change. */
.result-card {
  overflow: hidden;
  border: var(--border-thin) solid var(--color-primary);
  border-top: 4px solid var(--color-accent);
  border-radius: var(--radius);
  background: var(--color-card);
}

.result-card__title,
.result-card__headline,
.result-card__summary {
  margin: 0;
  padding: 0 var(--space-md);
  background: var(--color-primary);
}

.result-card__title {
  padding-top: var(--space-md);
  color: var(--color-on-primary-muted);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.result-card__headline {
  padding-top: var(--space-xs);
  color: var(--color-on-primary);
  font-family: var(--font-heading);
  font-size: clamp(var(--text-2xl), 1.6rem + 2vw, var(--text-3xl));
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.result-card__summary {
  padding-top: var(--space-sm);
  padding-bottom: var(--space-md);
  color: var(--color-on-primary);
}

/* Disclosures: detail that is one tap away. Used for paint details, the working and the checklist. */

.disclosure,
.working {
  margin-top: var(--space-sm);
}

.result-card .working {
  margin: 0;
  padding: var(--space-xs) var(--space-md) var(--space-sm);
}

.disclosure__summary,
.working__summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  min-height: 2.75rem;
  color: var(--color-link);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  transition: color var(--duration-state) var(--ease-out);
}

.disclosure__summary::-webkit-details-marker,
.working__summary::-webkit-details-marker {
  display: none;
}

.disclosure__summary:hover,
.working__summary:hover {
  color: var(--color-link-hover);
}

/* A chevron drawn with borders: points right when closed, down when open. */
.disclosure__summary::before,
.working__summary::before {
  content: "";
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  margin: 0 0.25rem 0 0.125rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--duration-state) var(--ease-out);
}

details[open] > .disclosure__summary::before,
details[open] > .working__summary::before {
  transform: translateY(-0.125rem) rotate(45deg);
}

.assumptions {
  margin-top: var(--space-smd);
}

.assumptions .tag {
  margin-left: var(--space-xs);
}

.breakdown {
  margin: 0;
}

.breakdown__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-sm) 0;
  border-top: var(--border-thin) solid var(--color-border);
}

.breakdown__row dt {
  min-width: 0;
}

.breakdown__row dd {
  margin: 0;
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.breakdown__row--strong dt,
.breakdown__row--strong dd {
  font-weight: 600;
}

.breakdown__working {
  display: block;
  color: var(--color-muted-foreground);
  font-size: var(--text-sm);
  font-weight: 400;
  overflow-wrap: anywhere;
}

/* Notices: an icon, a title in words, then the detail. */
.notice {
  display: flex;
  gap: var(--space-smd);
  padding: var(--space-smd) var(--space-md);
  border: var(--border-thin) solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-muted);
  font-size: var(--text-sm);
}

.notice > .icon {
  margin-top: 0.125rem;
  color: var(--color-link);
}

.notice--warning {
  border-color: var(--color-warning-text);
  background: var(--color-warning-tint);
}

.notice--warning > .icon,
.notice--warning .notice__title {
  color: var(--color-warning-text);
}

.notice__body {
  min-width: 0;
}

.notice__title {
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
}

.notice p,
.notice ul {
  margin-top: var(--space-xs);
}

.notice ul {
  padding-left: var(--space-md);
}

.notice__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-top: var(--space-smd);
}

/* Shopping list */

.checklist {
  margin-top: var(--space-sm);
  padding: 0 var(--space-md);
  border: var(--border-thin) solid var(--color-border);
  border-radius: var(--radius);
}

.checklist[open] {
  padding-bottom: var(--space-md);
}

.checklist .field--group {
  margin-top: var(--space-md);
}

.checklist__legend {
  font-weight: 600;
}

.shopping-list {
  margin-top: var(--space-md);
}

.shopping-list__intro {
  margin-top: 0;
  color: var(--color-muted-foreground);
}

/* The same warnings the result shows, repeated inside the list because the list is what gets copied and sent on. */
.shopping-list__warnings {
  margin-top: var(--space-smd);
  padding: var(--space-smd) var(--space-md);
  border: var(--border-thin) solid var(--color-warning-text);
  border-radius: var(--radius);
  background: var(--color-warning-tint);
  font-size: var(--text-sm);
}

.shopping-list__warnings-heading {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  color: var(--color-warning-text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
}

.shopping-list__warnings ul {
  margin-top: var(--space-xs);
  padding-left: var(--space-lg);
}

.shopping-list__heading {
  margin-top: var(--space-md);
  color: var(--color-muted-foreground);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.shopping-list__items {
  margin-top: var(--space-xs);
  padding-left: var(--space-lg);
}

.shopping-list__item {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.shopping-list__detail {
  display: block;
  color: var(--color-muted-foreground);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}

.shopping-list__footer {
  margin-top: var(--space-sm);
  color: var(--color-muted-foreground);
  font-size: var(--text-sm);
}

.shopping-list__section + .shopping-list__footer {
  margin-top: var(--space-md);
}

.list-actions {
  margin-top: var(--space-lg);
}

.list-actions__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-smd);
}

.list-actions__buttons .button {
  flex: 1 1 9rem;
}

.list-actions__status {
  display: flex;
  gap: var(--space-sm);
  color: var(--color-link);
  font-weight: 500;
}

.list-actions__status:empty {
  display: none;
}

.list-actions__manual {
  width: 100%;
  margin-top: var(--space-smd);
  padding: var(--space-sm);
  border: var(--border-thin) solid var(--color-control-border);
  border-radius: var(--radius);
  /* 16px like every other field: it takes focus so its text can be selected, and a phone would zoom on anything smaller. */
  font: var(--text-base) / 1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* Breakpoints: 768, 1024, 1440 */

@media (min-width: 48rem) {
  .page {
    padding: 0 var(--space-lg);
  }

  .site-header__name {
    font-size: var(--text-xl);
  }

  .site-nav a {
    padding: 0 var(--space-smd);
  }

  .lead {
    font-size: var(--text-lg);
  }

  .panel {
    padding: var(--space-lg);
  }

  .features,
  .module-list {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-lg);
  }

  .button--wide {
    width: auto;
    min-width: 16rem;
  }
}

@media (min-width: 64rem) {
  .calculator {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;
    gap: var(--space-xl);
  }
}

@media (min-width: 90rem) {
  .page {
    padding: 0 var(--space-xl);
  }
}

/* Motion: the estimate rises in once when it first appears, so a new answer is noticed.
   Nothing moves for decoration, and nothing moves at all for anyone who asks for reduced motion. */

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

.calculator__results.is-entering .results__details,
.calculator__results.is-entering .results__list {
  animation: rise-in var(--duration-enter) var(--ease-out) both;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Paper: the estimate and the list, nothing else. Dark surfaces become plain black on white. */

@media print {
  .no-print {
    display: none !important;
  }

  .print-only {
    display: block;
  }

  body {
    background: #fff;
    font-size: 11pt;
  }

  .page {
    max-width: none;
    padding: 0;
  }

  h1 {
    margin-top: 0;
    font-size: 22pt;
  }

  .lead {
    display: none;
  }

  .calculator {
    display: block;
    margin-top: var(--space-sm);
  }

  .panel {
    padding: 0;
    border: 0;
  }

  .result-card,
  .notice,
  .shopping-list__section {
    break-inside: avoid;
  }

  .result-card {
    border: 1px solid #000;
  }

  .result-card__title,
  .result-card__headline,
  .result-card__summary {
    background: none;
    color: #000;
  }

  /* The page opens the working before printing. This covers browsers that do not announce printing to scripts. */
  .working::details-content {
    content-visibility: visible;
    block-size: auto;
  }

  .working__summary::before {
    display: none;
  }

  .working__summary {
    min-height: 0;
    margin-top: var(--space-sm);
    color: #000;
  }

  :focus-visible {
    outline: none;
  }

  .calculator__results.is-entering .results__details,
  .calculator__results.is-entering .results__list {
    animation: none;
  }

  .site-footer {
    margin-top: var(--space-lg);
    padding: var(--space-smd) 0 0;
    color: #000;
  }
}

/* ---- Platform: directory, status badges, projects ---- */

/* A calculator's lifecycle state. Never decoration: it is the difference
   between a tool somebody has checked and one nobody has. */
.status-badge {
  display: inline-block;
  margin: 0 0 var(--space-sm);
  padding: 2px var(--space-sm);
  border: var(--border-thin) solid currentColor;
  border-radius: 4px;
  font-size: var(--text-sm);
  font-weight: 600;
}

.status-badge--draft {
  color: var(--color-warning-text);
  background: var(--color-warning-tint);
}

.status-badge--review,
.status-badge--reviewed {
  color: var(--color-link);
  background: var(--color-muted);
}

.category {
  margin-top: var(--space-2xl);
}

.category > .lead {
  margin-top: 0;
}

.calculator-search {
  margin-top: var(--space-lg);
}

.calculator-search .field__label {
  display: block;
}

.banner--info {
  align-items: flex-start;
}

/* ---- Saving an estimate to a project ---- */

.project-bar {
  margin-bottom: var(--space-lg);
}

.project-bar__body {
  padding: var(--space-md);
}

.project-bar__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-top: var(--space-md);
}

.project-bar__status:not(:empty) {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin-top: var(--space-md);
  color: var(--color-link);
}

.project-bar__new:not([hidden]) {
  margin-top: var(--space-md);
}

/* ---- The project page ---- */

.estimate-list {
  display: grid;
  gap: var(--space-md);
  margin: var(--space-md) 0 0;
  padding: 0;
  list-style: none;
}

.estimate {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  align-items: flex-start;
  justify-content: space-between;
}

.estimate h3 {
  margin: 0;
  font-size: var(--text-lg);
}

.estimate__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: center;
  margin: 0;
}

.project__add {
  margin-top: var(--space-lg);
  color: var(--color-muted-foreground);
  font-size: var(--text-sm);
}

@media print {
  .project-bar,
  .estimate-list,
  .project__add {
    display: none;
  }
}
