/* Palette — `specs/order-pad-redesign.md#palette`. Nine tokens, six values plus two
   neutrals, and every one of them is defined HERE, in the bare `:root`. A theme
   block below may only *redefine* a token; a colour whose sole definition sits
   behind a media query renders one theme's text on the other theme's ground. */
:root {
  --ground: #E8EAE6;
  --card: #FFFFFF;
  --ink: #14120E;
  --ink-2: #55594F;
  /* Decorative separators only. 1.60:1 on `--card`, so it can never bound a
     control — that is exactly the invariant `F-044` found asserted-but-unheld. */
  --rule: #C9CEC5;
  /* Any border that bounds a control. 4.70:1 on `--card`, clearing the 3:1 floor. */
  --rule-strong: #6E766B;
  /* Fill only, never a `color`: 1.85:1 on `--card`. The stylesheet test fails if
     it is ever used as text. */
  --accent: #F5B301;
  --positive: #1B5E42;
  --negative: #A3321E;

  /* The label on an `--accent` fill. `--accent` is identical in both themes, so a
     label painted with `--ink` would flip to 1.60:1 the moment the theme did.
     This one deliberately does NOT get redefined in the dark block. */
  --on-accent: #14120E;

  /* Type. The body face is still the system stack, deliberately: it is already on
     the device, so a back office opened on a phone in a stairwell renders its text
     with nothing to fetch. Only the DISPLAY face is a file, and it is served from
     this origin rather than a font CDN - the stairwell rule was about the network,
     and a same-origin subset costs one request that `font-display: swap` never
     blocks on. The Georgia fallback below is what renders while it arrives. */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --text-micro: 11px;
  --text-sm: 13px;
  --text-ui: 14px;
  --text-base: 15px;
  --text-lead: 17px;
}

/* Fraunces, variable, Latin subset, SIL Open Font License 1.1. One file, one axis
   range, one origin. `swap` is not optional here: it is what keeps a slow network
   showing Georgia rather than nothing. */
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("fonts/fraunces-latin.woff2") format("woff2");
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  min-width: 320px;
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-sans);
}

a {
  color: inherit;
}

h1, h2, h3, p {
  margin-top: 0;
}

h1, h2 {
  letter-spacing: -1.8px;
  line-height: 1.06;
}

h1 {
  font-size: clamp(42px, 5.5vw, 68px);
}

h1 em, h2 em {
  font-family: var(--font-display);
  font-weight: 600;
}

h2 {
  font-size: clamp(25px, 3vw, 38px);
}

/* The border is the only thing that says where the field is: no fill separates
   `--card` from the `--ground` page. That makes it a component boundary under
   SC 1.4.11, so it takes the interactive token, not the 1.33:1 hairline. */
input, select {
  width: 100%;
  min-height: 45px;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  padding: .7rem .8rem;
  background: var(--card);
  color: var(--ink);
  font: inherit;
}

input[type="file"] {
  padding: .52rem;
}

/* The rule above is written for a text field, and a checkbox is not one: full width,
   a 45px floor and field padding turn a 20px box into a stretched slab. Reported from
   the live order pad as "a huge checkbox that looks out of context from the others" -
   the society picker's box, which had never been rescued the way `.pad .tick` had.
   Exempting the type once is what stops the next checkbox re-discovering it. `flex:
   none` because `.society-choice` is a flex row, where the alternative to stretching
   is collapsing to a sliver. */
input[type="checkbox"] {
  width: 20px;
  height: 20px;
  min-height: 0;
  margin: 0;
  padding: 0;
  border-radius: 0;
  flex: none;
  accent-color: var(--positive);
}

label {
  display: grid;
  gap: 7px;
  color: var(--ink);
  font-size: var(--text-sm);
  font-weight: 800;
}

button {
  font: inherit;
}

a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
}

.app-shell {
  width: min(1160px, calc(100% - 40px));
  min-height: 100vh;
  margin-inline: auto;
}

.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 88px;
  gap: 24px;
  border-bottom: 1px solid var(--rule);
}

.brand-mark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
  text-decoration: none;
}

.brand-mark span {
  display: grid;
  width: 33px;
  height: 33px;
  place-items: center;
  background: var(--ink);
  color: var(--ground);
  font: 800 var(--text-micro) var(--font-mono);
  letter-spacing: -.1em;
}

.app-nav {
  display: flex;
  align-items: center;
  gap: 28px;
}

/* Named, not `.app-nav ul` — a descendant selector outweighs the single-class
   rules in the media blocks below, so the phone layout could never override it. */
.app-nav__primary, .app-nav__setup-list {
  display: flex;
  margin: 0;
  padding: 0;
  gap: 28px;
  list-style: none;
}

.app-nav a {
  color: var(--ink-2);
  font-size: var(--text-sm);
  font-weight: 800;
  text-decoration: none;
}

.app-nav a:hover {
  color: var(--ink);
}

.app-footer {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin-top: 88px;
  padding: 28px 0 36px;
  border-top: 1px solid var(--rule);
  color: var(--ink-2);
  font: var(--text-micro) var(--font-mono);
}

.skip-link {
  position: fixed;
  z-index: 3;
  top: 10px;
  left: 10px;
  padding: 10px 14px;
  background: var(--ink);
  color: var(--ground);
  text-decoration: none;
  transform: translateY(-160%);
}

.skip-link:focus {
  transform: translateY(0);
}

.eyebrow, .card-label {
  margin-bottom: 14px;
  color: var(--ink-2);
  font: 500 10px/1.5 var(--font-mono);
  letter-spacing: .09em;
  text-transform: uppercase;
}

.pulse-dot, .status-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--positive);
}

.pulse-dot {
  box-shadow: 0 0 0 4px var(--rule);
}

.flash {
  padding: 14px 16px;
  border: 1px solid;
  font-weight: 700;
}

.flash--error {
  border-color: var(--negative);
  background: var(--card);
  color: var(--negative);
}

.page-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(300px, .75fr);
  align-items: center;
  gap: 76px;
  min-height: 465px;
  padding: 62px 0;
}

.page-hero > div > p:not(.eyebrow), .page-heading > p:not(.eyebrow), .auth-intro > p:not(.eyebrow) {
  max-width: 600px;
  color: var(--ink-2);
  font-size: var(--text-lead);
  line-height: 1.75;
}

.signal-card {
  padding: 34px;
  background: var(--ground);
  border-top: 5px solid var(--positive);
  box-shadow: 10px 12px rgba(23, 38, 61, .08);
  transform: rotate(1deg);
}

.signal-card strong {
  display: block;
  font-size: clamp(26px, 3vw, 38px);
  line-height: 1.1;
  letter-spacing: -1.3px;
}

.signal-line {
  height: 5px;
  margin: 28px 0 18px;
  background: linear-gradient(90deg, var(--accent) 44%, var(--rule) 44%);
}

.signal-card p:last-child {
  margin-bottom: 0;
  color: var(--ink-2);
  font-size: 12px;
  font-weight: 700;
}

.action-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}

.action-card {
  display: flex;
  min-height: 265px;
  flex-direction: column;
  padding: 27px;
  border: 1px solid var(--rule);
  background: var(--card);
  text-decoration: none;
  transition: transform .2s, box-shadow .2s;
}

.action-card:hover {
  box-shadow: 8px 10px rgba(23, 38, 61, .08);
  transform: translateY(-3px);
}

.action-card--primary {
  border-top: 4px solid var(--positive);
  background: var(--ground);
}

.action-card > span {
  color: var(--ink-2);
  font: var(--text-micro) var(--font-mono);
}

.action-card h2 {
  margin: 45px 0 10px;
  font-size: 26px;
}

.action-card p {
  color: var(--ink-2);
  font-size: var(--text-sm);
  line-height: 1.65;
}

.action-card b {
  margin-top: auto;
  font-size: var(--text-sm);
}

.action-card i {
  margin-left: 4px;
  color: var(--ink-2);
  font-style: normal;
}

.signout-form {
  margin-top: 28px;
}

/* A header, not a banner. `F-023` measured the display `h1` plus its eyebrow and
   description spending ~230px before the first control — a quarter of a 844px
   phone viewport, on every screen, to restate the tab just tapped. The display
   clamp survives only where it costs nothing: `/login`, via the bare `h1` rule. */
.page-heading {
  max-width: 740px;
  padding: 32px 0 24px;
}

.page-heading h1 {
  margin-bottom: 12px;
  font-size: clamp(24px, 4vw, 32px);
  letter-spacing: -.6px;
}

/* Identifies the record a screen is showing; it belongs with the record. */
.record-identity {
  margin-bottom: 20px;
  color: var(--ink-2);
  font-size: var(--text-base);
}

.panel {
  padding: 30px;
  border: 1px solid var(--rule);
  background: var(--card);
  box-shadow: 7px 9px rgba(23, 38, 61, .035);
}

.panel h2 {
  margin-bottom: 24px;
}

.compact-form, .auth-card {
  display: grid;
  gap: 15px;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 17px;
  min-height: 47px;
  padding: 12px 18px;
  border: 0;
  border-radius: 2px;
  font-size: var(--text-sm);
  font-weight: 800;
  cursor: pointer;
  transition: transform .2s, background .2s;
}

.button:hover {
  transform: translateY(-2px);
}

/* Repointed at the new tokens rather than deleted: every template still names it,
   and the deletions are `OP-14`'s job, after every screen has been converted. */
.button--primary {
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: 4px 4px var(--rule-strong);
}

.button--dark {
  background: var(--ink);
  color: var(--ground);
}

.empty-state {
  color: var(--ink-2);
  font-size: var(--text-sm);
  line-height: 1.6;
}

.workflow-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}

.workflow-grid .panel {
  padding: 24px;
}

.workflow-grid .panel h2 {
  font-size: 26px;
}

.selected-window {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 30px;
  margin: 54px 0 20px;
  padding: 32px;
  background: var(--ground);
  border-top: 4px solid var(--positive);
}

.selected-window h2 {
  margin-bottom: 8px;
}

.selected-window p:last-child {
  margin-bottom: 0;
  color: var(--ink-2);
  font-size: 14px;
}

.order-line {
  display: grid;
  grid-template-columns: 1fr .55fr;
  gap: 12px;
}

.tenant-form {
  display: grid;
  max-width: 560px;
  gap: 15px;
}

.window-actions {
  display: grid;
  justify-items: start;
  gap: 15px;
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  margin-bottom: 20px;
}

.summary-grid article {
  padding: 25px;
  border: 1px solid var(--rule);
  background: var(--card);
}

.summary-grid span {
  display: block;
  margin-bottom: 24px;
  color: var(--ink-2);
  font: 10px var(--font-mono);
  letter-spacing: .08em;
  text-transform: uppercase;
}

.summary-grid strong {
  font-size: clamp(25px, 3vw, 38px);
  letter-spacing: -1.4px;
}

.summary-grid__revenue {
  background: var(--ink) !important;
  color: var(--ground);
}

.summary-grid__revenue span {
  color: var(--ground);
}

.report-panel {
  margin-bottom: 20px;
}

.summary-table {
  width: 100%;
  border-collapse: collapse;
}

.summary-table th, .summary-table td {
  padding: 15px 0;
  border-top: 1px solid var(--rule);
  text-align: left;
}

.summary-table th {
  color: var(--ink-2);
  font: 10px var(--font-mono);
  letter-spacing: .07em;
  text-transform: uppercase;
}

.summary-table td:last-child, .summary-table th:last-child {
  text-align: right;
}

.summary-table td:nth-child(2), .summary-table th:nth-child(2) {
  text-align: center;
}

.order-filter {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 15px;
  margin-bottom: 28px;
}

.flash--done {
  border-color: var(--positive);
  background: var(--ground);
  color: var(--ink);
}

.review-list {
  display: grid;
  gap: 8px;
  margin: 0 0 20px;
  padding: 0;
  list-style: none;
}

/* Collapsed to one line each so twelve households is a list to scroll rather
   than a grid to fill. A card with nothing typed opens itself, because an
   empty card is the one thing that will reject the batch. */
.review-card {
  padding: 12px;
  border: 2px solid var(--rule-strong);
  background: var(--card);
}

.review-card summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  min-height: 44px;
  padding: 6px 0;
  cursor: pointer;
}

.review-card summary small {
  flex-basis: 100%;
  color: var(--ink-2);
}

.review-card[open] {
  border-color: var(--positive);
}

.repeat-marker {
  padding: 2px 8px;
  border: 1px solid var(--positive);
  background: var(--ground);
  color: var(--ink);
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .08em;
}

.app-shell--login {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}

.app-shell--login .app-header {
  border: 0;
}

.auth-layout {
  display: grid;
  grid-template-columns: 1.05fr .75fr;
  align-items: center;
  gap: clamp(40px, 10vw, 130px);
  flex: 1;
  padding: 70px 0 105px;
}

.auth-intro h1 {
  max-width: 620px;
  margin-bottom: 24px;
}

.auth-note {
  margin-top: 26px !important;
  color: var(--ink-2) !important;
  font: var(--text-micro) var(--font-mono) !important;
}

.auth-card {
  padding: 35px;
  border-top: 5px solid var(--positive);
  background: var(--ground);
  box-shadow: 10px 12px rgba(23, 38, 61, .08);
}

.auth-card h2 {
  margin-bottom: 8px;
}

.auth-card .button {
  margin-top: 8px;
}

.app-shell--login .app-footer {
  margin-top: auto;
}

@media (max-width: 800px) {
  .app-shell {
    width: min(100% - 32px, 1160px);
  }

  .app-header {
    min-height: 74px;
  }

  .app-nav {
    gap: 16px;
  }

  .app-nav a {
    font-size: 11px;
  }

  .page-hero, .auth-layout {
    grid-template-columns: 1fr;
    gap: 30px;
  }

  .page-hero {
    min-height: auto;
    padding: 50px 0;
  }

  .signal-card {
    transform: none;
  }

  .action-grid, .workflow-grid {
    grid-template-columns: 1fr;
  }

  .action-card {
    min-height: 210px;
  }

  .action-card h2 {
    margin-top: 28px;
  }

  .page-heading {
    padding: 20px 0 16px;
  }

  .selected-window {
    align-items: flex-start;
    flex-direction: column;
    margin-top: 38px;
  }

  .auth-layout {
    padding: 38px 0 70px;
  }

  .app-footer {
    margin-top: 56px;
  }

  .workflow-grid .panel {
    padding: 28px;
  }
}

@media (max-width: 800px) {
  .auth-layout > *, .workflow-grid > * {
    min-width: 0;
  }

  h1 {
    overflow-wrap: anywhere;
  }
}

@media (max-width: 800px) {
  .summary-grid {
    grid-template-columns: 1fr;
  }

  .summary-table {
    font-size: var(--text-sm);
  }

  .selected-window {
    align-items: flex-start;
  }

  .window-actions {
    justify-items: start;
  }
}

/* Phone-first shell. Daily work sits in the thumb zone; the four one-time setup
   destinations are one level up, behind the header's Setup entry and `/setup`. */
@media (max-width: 800px) {
  .app-nav__primary {
    position: fixed;
    z-index: 4;
    right: 0;
    bottom: 0;
    left: 0;
    height: calc(56px + env(safe-area-inset-bottom));
    gap: 0;
    padding-bottom: env(safe-area-inset-bottom);
    border-top: 1px solid var(--rule-strong);
    background: var(--card);
  }

  .app-nav__primary li {
    display: flex;
    flex: 1;
  }

  .app-nav__primary a {
    display: grid;
    min-width: 64px;
    min-height: 48px;
    flex: 1;
    align-content: center;
    border-top: 3px solid transparent;
    font-size: var(--text-sm);
    text-align: center;
  }

  .app-nav__primary a[aria-current="page"] {
    border-top-color: var(--positive);
    color: var(--positive);
  }

  .app-nav__setup-list {
    display: none;
  }

  .app-nav__setup-link {
    display: grid;
    min-width: 64px;
    min-height: 48px;
    align-content: center;
  }

  /* The bar is fixed, so the last control on a long screen would sit under it. */
  .app-shell:not(.app-shell--login) main {
    padding-bottom: calc(56px + env(safe-area-inset-bottom) + 16px);
  }

  .app-shell:not(.app-shell--login) .app-footer {
    padding-bottom: calc(36px + 56px + env(safe-area-inset-bottom));
  }
}

@media (max-width: 480px) {
  .app-nav {
    gap: 11px;
  }

  .brand-mark strong {
    font-size: 14px;
  }

  .panel, .auth-card, .selected-window {
    padding: 23px;
  }

  .app-footer {
    flex-direction: column;
  }

  .order-filter, .order-line {
    grid-template-columns: 1fr;
  }
}

@media (min-width: 801px) {
  .app-shell:not(.app-shell--login) {
    display: grid;
    width: min(1280px, calc(100% - 48px));
    grid-template-columns: 220px minmax(0, 1fr);
    column-gap: 52px;
  }

  .app-shell:not(.app-shell--login) .app-header {
    align-items: flex-start;
    align-self: start;
    min-height: 100vh;
    flex-direction: column;
    justify-content: flex-start;
    padding-top: 32px;
    border-bottom: 0;
    border-right: 1px solid var(--rule);
  }

  /* The bottom bar re-flows into the 220px rail. Same markup, different CSS —
     a second nav block would let a new destination appear in only one of them. */
  .app-shell:not(.app-shell--login) .app-nav {
    width: 100%;
    align-items: stretch;
    flex-direction: column;
    gap: 32px;
    margin-top: 52px;
    padding-right: 24px;
  }

  .app-nav__primary {
    position: static;
    height: auto;
    flex-direction: column;
    gap: 6px;
    border-top: 0;
  }

  .app-nav__setup-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
  }

  .app-nav__setup-link {
    display: block;
    margin-bottom: 10px;
    padding: 0 12px;
    color: var(--ink-2);
    font: 500 10px/1.5 var(--font-mono);
    letter-spacing: .12em;
    text-transform: uppercase;
  }

  .app-nav__primary a, .app-nav__setup-list a {
    padding: 10px 12px;
  }

  .app-nav a[aria-current="page"] {
    background: var(--ground);
    color: var(--ink);
  }

  .app-shell:not(.app-shell--login) main, .app-shell:not(.app-shell--login) .app-footer {
    grid-column: 2;
  }

  .app-shell:not(.app-shell--login) .app-footer {
    margin-top: 60px;
  }
}

.inline-edit {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 12px;
}

.inline-edit input {
  min-width: 0;
}

/* A negative margin is shown as the negative number it is. Selling below cost is
   exactly what this figure exists to reveal, so it is never clamped or hidden. */
.margin {
  font-weight: 800;
}

.margin--negative {
  color: var(--negative);
}

/* Never "₹0.00". An unknown cost and a zero cost are different facts, and the
   first one reading as the second is what made planned profit equal gross sales. */
.unknown-cost {
  color: var(--ink-2);
  font-style: italic;
}

/* ---------------------------------------------------------------------------
   The button system — `specs/order-pad-redesign.md#the-button-system`.

   One base, four variants. Every variant is `inline-flex` with the same padding
   rhythm and NOTHING sets its own `height`, so nothing can drift: the three
   systems this replaces measured 47px, 44px and zero. `.btn--sm` is the single
   exception at 34px, permitted only inside a table row whose own padding supplies
   the rest of the target area.

   `.btn--go` is the only variant that carries the accent, and it carries it as a
   fill. `--accent` is 1.85:1 on paper and is never a text colour.
   --------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 44px;
  padding: 10px 18px;
  border: 1px solid transparent;
  border-radius: 2px;
  background: transparent;
  color: var(--ink);
  font-family: inherit;
  font-size: var(--text-ui);
  font-weight: 800;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

/* The one action that commits this screen's work. */
.btn--go {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--on-accent);
}

/* A secondary action: ink border, paper fill. */
.btn--line {
  border-color: var(--ink);
  background: var(--card);
  color: var(--ink);
}

/* Navigational or reversible: underlined text, no border. */
.btn--quiet {
  color: var(--ink-2);
  text-decoration: underline;
}

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

/* Remove or withdraw. */
.btn--danger {
  color: var(--negative);
  text-decoration: underline;
}

/* Only inside a table row. The row's padding supplies the rest of the target. */
.btn--sm {
  min-height: 34px;
  padding: 6px 12px;
  font-size: var(--text-sm);
}

/* Any group of two or more buttons is wrapped in this — `ingredients.html:106`
   places two adjacent with no wrapper at all, inside `align-items: end`. */
.btn-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

/* ---------------------------------------------------------------------------
   Dark theme. Only a REDEFINITION: every token above already has a value in the
   bare `:root`, and the stylesheet test fails if one is introduced here first.
   `--accent` and `--on-accent` are deliberately absent — the accent is the same
   turmeric in both themes, so its label must stay the dark ink.
   --------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root {
    --ground: #161714;
    --card: #1E201C;
    --ink: #EDEFE7;
    --ink-2: #A3A89B;
    --rule: #33362F;
    --rule-strong: #7C8377;
    --positive: #5FD39D;
    --negative: #F08A72;
  }
}

/* ---------------------------------------------------------------------------
   The table primitive — `specs/order-pad-redesign.md#the-table-primitive`.

   One markup shape for every master screen: a `.pad` wrapping a table whose
   first `<tbody>` row is the add form, in the same columns as the saved rows.
   Nothing renders it yet; `OP-05`..`OP-10` convert the screens one at a time.

   `.pad` is the scroll container AND the containment context. Both matter: the
   overflow has to stop here rather than reaching the page body, and the fold
   below is a container query, so without `container-type` those rules would
   parse, match nothing, and leave the phone layout inert.
   --------------------------------------------------------------------------- */
.pad {
  container-type: inline-size;
  max-width: 100%;
  overflow-x: auto;
  border: 1px solid var(--rule-strong);
  background: var(--card);
}

.pad table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-ui);
}

.pad th, .pad td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--rule);
  text-align: left;
  vertical-align: middle;
}

.pad thead th {
  border-bottom: 1px solid var(--rule-strong);
  color: var(--ink-2);
  font: 500 10px/1.5 var(--font-mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.pad tbody tr:last-child td {
  border-bottom: 0;
}

/* The actions column. Right-aligned and never wrapped, so a two-button row stays
   one row; the buttons themselves are `.btn--sm` inside `.btn-row`. */
.pad .act {
  text-align: right;
  white-space: nowrap;
}

/* The add row's 3px accent border on its first cell. Per the spec this marker is
   the ONLY place row state is encoded, so this block sets one property and no
   other rule in the file names `.add-row` — a fill or a weight here would be a
   second encoding competing with it. `--accent` is 1.85:1 on paper and can only
   ever be a border, never the text beside it. */
.add-row td:first-child {
  border-left: 3px solid var(--accent);
}

/* A row thumbnail. Square, small, and aligned with the name beside it, because in a
   table the picture is an identifier rather than a subject: at 34px it tells one dish
   from another at a glance without turning the row into a card. An item with no image
   keeps the same box holding its initial, so the name column never shifts sideways
   between a row that has a photo and a row that does not. */
.row-thumb {
  display: inline-flex;
  width: 34px;
  height: 34px;
  margin-right: 10px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--rule-strong);
  background: var(--ground);
  color: var(--ink-2);
  font: 700 var(--text-sm)/1 var(--font-mono);
  object-fit: cover;
  vertical-align: middle;
}

/* A status pill. The only two states a window has, and the one thing this list is
   scanned for, so it reads as a shape rather than as another word in a row of words.
   Both states carry a border as well as a tint: the tints are deliberately weak - a
   fill strong enough to carry white text would compete with the accent, which the
   spec reserves for the one committing action on a screen - so the border is what
   makes the pill legible, and the text colour is what makes the two states differ at
   the required ratio rather than by hue alone. */
.pill {
  display: inline-flex;
  min-height: 24px;
  align-items: center;
  padding: 2px 10px;
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: var(--text-sm);
  font-weight: 700;
  white-space: nowrap;
}

.pill--open {
  color: var(--positive);
}

.pill--closed {
  color: var(--ink-2);
}

/* Choosing which buildings this round covers. A set of checkboxes rather than a
   multi-select: a `<select multiple>` on a phone is a scrolling box that needs a
   modifier key to add a second choice, which is exactly the round this row exists to
   make possible. Each label carries the 44px floor because it is the tap target. */
.society-picker {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 12px;
  padding: 0;
  border: 0;
}

.society-picker legend {
  padding: 0;
  color: var(--ink-2);
  font: 500 10px/1.5 var(--font-mono);
  letter-spacing: .08em;
  text-transform: uppercase;
}

.society-choice {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border: 1px solid var(--rule-strong);
  background: var(--card);
  font-size: var(--text-ui);
  cursor: pointer;
}

.society-choice:has(input:checked) {
  border-width: 2px;
  padding: 5px 11px;
}

/* The expanded locality's societies, in a row of their own beneath it. The nested
   `.pad` is its own containment context, which is the point of using a container query
   for the fold rather than a media query: this table is narrow on a laptop, and no
   viewport rule could ever know that. The inset and the left rule are what say the
   nested table belongs to the row above rather than to the list. */
.drill {
  padding: 14px 14px 14px 24px;
  border-left: 3px solid var(--rule-strong);
  background: var(--ground);
}

/* The folded sub-line, hidden while the columns it duplicates are visible. */
.pad .fold {
  display: none;
}

/* Below ~700px of CONTAINER width — not viewport. A nested `.pad` (the societies
   table inside an expanded locality) is narrow on a laptop, and a media query
   cannot see that. Columns whose content repeats elsewhere are marked `.opt` and
   fold into `.fold` under the first cell: same DOM, same markers, no horizontal
   scroll. This block may only style DESCENDANTS of `.pad`; a container never
   matches its own query. */
@container (max-width: 700px) {
  .pad .opt {
    display: none;
  }

  .pad .fold {
    display: block;
    margin-top: 3px;
    color: var(--ink-2);
    font-size: var(--text-sm);
    line-height: 1.45;
  }

  .pad th, .pad td {
    padding: 10px 12px;
  }
}

/* ---------------------------------------------------------------------------
   Search and paging — the controls above and below every `.pad`.

   `OP-04` builds the bounded, searched repository reads that feed these; this row
   owns only their appearance. The search field is a bare `input`, which already
   carries the 45px floor and the interactive border; the pager's controls declare
   the 44px floor on both axes because a pager is operated with a thumb.
   --------------------------------------------------------------------------- */
.searchbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  margin-bottom: 16px;
}

.searchbar label {
  flex: 1 1 220px;
  min-width: 0;
}

.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 16px;
}

.pager__count {
  color: var(--ink-2);
  font-size: var(--text-sm);
}

.pager a, .pager button {
  display: inline-flex;
  min-width: 44px;
  min-height: 44px;
  align-items: center;
  justify-content: center;
  padding: 10px 14px;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  background: var(--card);
  color: var(--ink);
  font-size: var(--text-sm);
  font-weight: 800;
  text-decoration: none;
  cursor: pointer;
}

/* Kept at full contrast on purpose: the edge of an unavailable page still has to
   be findable by touch, and the decorative hairline may never bound a control. */
.pager [aria-disabled="true"], .pager button:disabled {
  color: var(--ink-2);
  cursor: default;
}

/* Visually hidden, still announced. The primitive's actions column has a `.sr`
   label in its header; `display: none` would take that out of the accessibility
   tree, which is the one thing this class must not do. */
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   The order register — stage 1 of `/orders/new`.

   This screen was the last one still rendering a bordered card per customer:
   twenty 2px boxes down the page, nested inside a fieldset inside a panel. It
   now uses the same `.pad` table every other screen uses, so almost everything
   below is state the other screens have no need for, not a second design.
   --------------------------------------------------------------------------- */

/* The tick column. Narrow, centred, and never folded away: it is the one control
   in the row, so `.opt` would hide the only thing the row is for. */
/* No vertical padding of its own: the 44px label inside already sets the row's
   height, and adding the cell's 12px on top of it made every row 70px - a page of
   25 households nearly two screens long, which is the density this redesign exists
   to fix. The tap target is unchanged; only the double-counting is gone. */
.pad .tick {
  width: 1%;
  padding-top: 0;
  padding-bottom: 0;
  padding-right: 0;
  text-align: center;
}

/* The tap target is the label, not the box. A checkbox drawn at 44px is a slab;
   a 44px target around a 20px box is what a thumb actually needs, and clicking a
   label toggles the control it wraps with no scripting involved. */
.pad .tick__hit {
  display: flex;
  min-height: 44px;
  min-width: 44px;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}


/* Selection, marked the way the add row is marked: a border on the first cell.
   `F-006` measured selected against unselected at 1.01:1 when a tint carried it
   alone - no fill in this palette can reach 3:1 on `--card` - so the border does
   the work and `--ground` only supports it. `--positive` clears 3:1; `--accent`
   would not, and is reserved for the add row besides. */
.pad tbody tr:has(input[name="selected_customer_id"]:checked) {
  background: var(--ground);
}

.pad tbody tr:has(input[name="selected_customer_id"]:checked) td:first-child {
  border-left: 3px solid var(--positive);
}

/* What this household already took, and the two things that can be done about it.
   Not `.act`: that column never wraps, and an order summary plus two controls in
   one unwrapped line is what pushes the table into a horizontal scroll. */
.pad .took {
  min-width: 180px;
  text-align: right;
}

/* On the same line as the pill, so an ordered row is the same height as a plain
   one. Stacked, it ran 14px taller, and a list whose rows are two different
   heights is measurably slower to scan than one whose rows are all alike - which
   is the whole benefit a table has over the cards this replaced. It still wraps
   when the column is too narrow to hold both; nothing is pinned to one line. */
.pad .took {
  white-space: normal;
}

.pad .took .btn-row {
  display: inline-flex;
  justify-content: flex-end;
  gap: 10px;
  margin-left: 10px;
  font-size: var(--text-sm);
  vertical-align: middle;
}

.pad .took a, .pad .took button {
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 700;
  text-decoration: underline;
  cursor: pointer;
}

/* Recorded, in the same pill shape the window list uses for its two states, so
   "this is a status" is one shape across the application rather than two. */
.pill--took {
  color: var(--positive);
}

/* A row with no order says so with a mark rather than a blank: an empty cell reads
   as missing data, and this cell is never missing - it is answered, with "none". */
.took__none {
  color: var(--ink-2);
}

/* Ordered / not ordered, and the totals that describe them. A segmented control
   rather than a dropdown: three mutually exclusive views of one list, all three
   worth reading at once because the numbers are the summary. */
.tally {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 16px;
}

.tally__seg {
  display: flex;
  min-height: 44px;
  flex: 1 1 120px;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 1px;
  padding: 6px 14px;
  border: 1px solid var(--rule-strong);
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
  text-align: left;
}

.tally__seg b {
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 600;
  line-height: 1;
}

.tally__seg span {
  color: var(--ink-2);
  font: 500 10px/1.5 var(--font-mono);
  letter-spacing: .08em;
  text-transform: uppercase;
}

/* The chosen view. Marked by a solid left rule at 4.70:1, never by fill alone -
   the same reason the selected row is bordered rather than tinted. */
.tally__seg--on {
  border-left: 3px solid var(--ink);
  background: var(--ground);
}

.tally__seg--on span {
  color: var(--ink);
}

/* Rows per page, sitting in the pager because that is the control it changes. */
.rows-choice {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  gap: 8px;
  color: var(--ink-2);
  font: 500 10px/1.5 var(--font-mono);
  letter-spacing: .08em;
  text-transform: uppercase;
}

.rows-choice select {
  width: auto;
  min-height: 44px;
}

/* The one place this screen moves. A row settling into its selected state is the
   feedback that a tick registered; anything more would be decoration on a screen
   whose job is entering fifty orders quickly. */
.pad tbody tr {
  transition: background 120ms ease-out;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* The register's own narrow branch. A SECOND `@container` block, deliberately, and
   it has to live here rather than in the fold block above: these selectors are the
   same specificity as the base rules a few lines up, so at equal weight the later
   one wins. Written into the earlier block, every rule below parsed, matched, and
   was overridden by the very rule it existed to override - green stylesheet, wide
   table, nothing to see in either file alone. */
@container (max-width: 700px) {
  /* The order column gives up its floor. Held at 180px it made the table wider than
     a 390px phone, so `.pad` scrolled sideways and the name column was squeezed until
     "Asha Kulkarni" broke across two lines - a horizontal scroll to read a column,
     caused by a rule meant to prevent one. */
  .pad .took {
    min-width: 0;
  }

  /* The pill folds like any other column: what they took joins the sub-line under
     the name, where the society, flat and mobile already went. Left in a 113px
     column it wrapped "Litti Chokha x4" over three lines and made an ordered row
     twice the height of a plain one. Only the two CONTROLS stay in the column -
     text folds, controls do not, because a control moved into a sub-line is a
     control the thumb has to hunt for. */
  .pad .took .pill {
    display: none;
  }

  .pad .took .btn-row {
    display: flex;
    margin-top: 4px;
    margin-left: 0;
  }
}
