/* ── Reset & tokens ──────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --font-heading: 'Palatino Linotype', Palatino, 'Book Antiqua', Georgia, serif;
  --font-body: 'Segoe UI', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
  --font-list: var(--font-body);
  --radius: 8px;
  --radius-sm: 4px;
  --radius-lg: 14px;
  --radius-pill: 999px;
  --space-control: 0.5rem;
  --space-card: 1rem;
  --space-section: 1.5rem;
  --transition: 160ms ease;
  /* Elevation is assembled from theme-owned colours below. Keeping the
     geometry here gives every theme the same physical hierarchy while the
     tint and strength remain appropriate to its paper or dark surface. */
  --shadow-raised:
    inset 0 1px 0 var(--color-surface-highlight),
    0 2px 3px var(--color-shadow-key),
    0 8px 18px var(--color-shadow-ambient);
  --shadow-raised-hover:
    inset 0 1px 0 var(--color-surface-highlight),
    0 3px 4px var(--color-shadow-key),
    0 12px 26px var(--color-shadow-ambient);
  --shadow-control:
    inset 0 1px 0 var(--color-surface-highlight),
    0 2px 0 var(--color-shadow-key),
    0 3px 7px var(--color-shadow-ambient);
  --shadow-control-hover:
    inset 0 1px 0 var(--color-surface-highlight),
    0 3px 0 var(--color-shadow-key),
    0 5px 10px var(--color-shadow-ambient);
  --shadow-control-pressed:
    inset 0 2px 4px var(--color-shadow-key),
    0 1px 1px var(--color-shadow-ambient);
  --shadow-recessed: inset 0 2px 4px var(--color-shadow-inset);
  --shadow-overlay:
    inset 0 1px 0 var(--color-surface-highlight),
    0 4px 8px var(--color-shadow-key),
    0 18px 38px var(--color-shadow-ambient);
  --shadow-nav:
    0 2px 2px var(--color-shadow-key),
    0 7px 16px var(--color-shadow-ambient);
  --max-w: 1280px;
  --nav-h: 56px;
  --footer-h: 36px;
  /* Shared control heights. Buttons, inputs and selects sit on the same
     baseline wherever they share a row, which is most toolbars in the app. */
  --control-h: 40px;
  --control-h-sm: 32px;
  --control-h-xs: 26px;
  /* Smallest comfortable tap target for icon-only buttons. */
  --tap: 44px;
}

html { font-size: 16px; -webkit-text-size-adjust: 100%; overflow-x: hidden; }

body {
  font-family: var(--font-body);
  background: var(--color-bg);
  color: var(--color-text);
  line-height: 1.6;
  min-height: 100vh;
  min-height: 100dvh;
  width: 100%;
  overflow-x: hidden;
  overflow-x: clip;
  overscroll-behavior: none;
  transition: background var(--transition), color var(--transition);
}

h1, h2, h3 { font-family: var(--font-heading); font-weight: 600; line-height: 1.3; }
a { color: var(--color-accent); text-decoration: none; }
a:hover { text-decoration: underline; }
button { cursor: pointer; font-family: inherit; }
input, select, textarea { font-family: inherit; font-size: 1rem; }
ul { list-style: none; }
[x-cloak] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

/* One keyboard focus ring for the whole app. Most controls here are custom
   borderless buttons, which otherwise get no visible focus at all. */
a:focus,
button:focus,
input:focus,
select:focus,
textarea:focus,
summary:focus,
label:focus,
[tabindex]:focus {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
label:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* ── Nav ─────────────────────────────────────────────────────────────── */
.nav {
  position: sticky; top: 0; z-index: 100;
  width: 100%;
  height: var(--nav-h);
  background: var(--color-nav-bg);
  color: var(--color-nav-text);
  display: flex; align-items: center; gap: 1rem;
  padding: 0 1.25rem;
  box-shadow: var(--shadow-nav);
}

.nav__logo {
  font-family: var(--font-heading);
  font-size: 1.3rem; font-weight: 700;
  color: var(--color-nav-text);
  text-decoration: none;
  white-space: nowrap;
}

.nav__links {
  display: flex; align-items: center; gap: 0.25rem;
  flex: 1;
}

.nav__right {
  display: flex; align-items: center; gap: 0.5rem;
  margin-left: auto;
}

.nav__name {
  font-size: 0.875rem;
  opacity: 0.75;
  white-space: nowrap;
}

.nav__link {
  padding: 0.35rem 0.65rem;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  color: var(--color-nav-text);
  opacity: 0.8;
  transition: opacity var(--transition), background var(--transition);
  white-space: nowrap;
}
.nav__link:hover { opacity: 1; background: rgba(255,255,255,0.08); text-decoration: none; }
.nav__link--active { opacity: 1; background: rgba(255,255,255,0.15); font-weight: 600; }
.nav__link--icon { font-size: 1.1rem; padding: 0.35rem 0.5rem; }

.nav__logout-form { display: inline; }

/* Collapsed navigation */
.nav__burger {
  display: none; flex-direction: column; gap: 5px; cursor: pointer;
  width: 44px; height: 44px; justify-content: center;
  padding: 0.45rem; border: 1px solid rgba(255,255,255,0.45);
  border: 1px solid var(--color-border); border: 1px solid color-mix(in srgb, var(--color-nav-text) 45%, transparent);
  border-radius: var(--radius-sm); background: rgba(255,255,255,0.12);
  background: var(--color-bg-secondary); background: color-mix(in srgb, var(--color-nav-text) 12%, transparent);
}
.nav__burger span { display: block; width: 24px; height: 3px; background: var(--color-nav-text); border-radius: 2px; transition: transform var(--transition); }

/* The complete desktop navigation needs substantially more room than a
   phone-only breakpoint allows. Collapse it on tablets and landscape phones
   too, otherwise the page links and account controls overlap or fall outside
   the viewport. */
@media (max-width: 1180px) {
  :root { --nav-h: 52px; }
  .nav { padding: 0 0.75rem; gap: 0.5rem; }
  .nav__logo { font-size: 1.05rem; }
  .nav__links {
    display: none; position: absolute; top: var(--nav-h); left: 0; right: 0;
    background: var(--color-nav-bg); flex-direction: column; padding: 0.5rem 1rem;
    box-shadow: 0 4px 12px var(--color-shadow);
    max-height: calc(100dvh - var(--nav-h) - var(--footer-h) - env(safe-area-inset-bottom, 0px));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .nav__links .nav__link { width: 100%; }
  .nav__links--open { display: flex; }
  .nav__burger { display: flex; }
  .nav__burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
  .nav__burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .nav__burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }
  .nav__right { margin-left: auto; }
  .nav__name { max-width: 10rem; overflow: hidden; text-overflow: ellipsis; }
}

@media (max-width: 640px) {
  :root { --footer-h: 44px; }
  .nav__name { display: none; }
  .nav__logout-form .btn { padding: 0.3rem 0.45rem; font-size: 0.78rem; }
}

/* ── Main ────────────────────────────────────────────────────────────── */
.main {
  max-width: var(--max-w);
  margin: 0 auto;
  width: 100%;
  padding: 1.25rem 1.25rem calc(var(--footer-h) + env(safe-area-inset-bottom, 0px) + 4px);
}
@media (max-width: 640px) {
  .main {
    max-width: none;
    /* Fixed height: fills between nav and footer. Makes .main the scroll container,
       which is required for reliable scroll in mobile PWA (body scroll + fixed footer is broken on iOS). */
    height: calc(100vh - var(--nav-h) - var(--footer-h) - env(safe-area-inset-bottom, 0px));
    height: calc(100dvh - var(--nav-h) - var(--footer-h) - env(safe-area-inset-bottom, 0px));
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 0.6rem 0.5rem 1.5rem;
  }
}

/* ── Pages that own their scrolling ──────────────────────────────────── */
/* The two rules above make .main the scroll container on phones, and the
   comment there gives the reason: a scrolling body underneath a fixed footer is
   unreliable in a mobile PWA. A wall-mounted tablet in standalone mode is that
   same case at a size neither rule covers (1024x600 is too wide for the first
   and too tall for the second), and the customisable Board is routinely taller
   than the screen, so it would scroll the body on exactly the device where that
   is known to detach the footer. Opt those pages in at every size instead. */
.main--own-scroll {
  height: calc(100vh - var(--nav-h) - var(--footer-h) - env(safe-area-inset-bottom, 0px));
  height: calc(100dvh - var(--nav-h) - var(--footer-h) - env(safe-area-inset-bottom, 0px));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* ── Landscape mobile scroll ─────────────────────────────────────────── */
/* Phones in landscape are wider than 640px so the desktop layout kicks in,
   but the viewport is only ~360-420px tall. Switch to a single-scroll-container
   model so content is reachable instead of clipped by overflow:hidden panels. */
@media screen and (max-height: 500px) and (min-width: 641px) {
  .main {
    height: calc(100dvh - var(--nav-h) - var(--footer-h) - env(safe-area-inset-bottom, 0px));
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 0.6rem max(0.75rem, env(safe-area-inset-right, 0px)) 1.5rem max(0.75rem, env(safe-area-inset-left, 0px));
  }
}

/* ── Board layout ────────────────────────────────────────────────────── */
.board {
  display: grid;
  grid-template-columns: minmax(280px, 380px) 1fr;
  gap: 1.25rem;
  align-items: start;
}
/* Mobile swipe tabs, hidden on desktop */
.board__tabs { display: none; }

.board__left {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.board__centre {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  min-width: 0;
}

/* Right sidebar: hidden until screen is wide enough */
.board__weather { display: none; }

/* 1024px covers both current and older iPad Mini in landscape (1133px and
   1024px respectively), which read cleanly at this column layout; below
   that, item text and headings start wrapping badly (verified down to
   901px), so a squeezed two-column fallback takes over instead. */
@media (min-width: 1024px) {
  .board--sidebar {
    grid-template-columns: minmax(280px, 380px) 1fr 260px;
    align-items: start;
  }
  .board--sidebar .board__weather {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    /* Let panels keep their content height; the page scrolls on short tablets. */
  }
  .board--sidebar .board__weather .watch-list {
    max-height: 16rem;
    overflow-y: auto;
  }
  /* Time since/until live in the sidebar at this width; hide the left-column copies */
  .board--sidebar .board__watches--left,
  .board--sidebar .board__countdown--left,
  .board--sidebar .board__chores--left {
    display: none;
  }
}

@media (max-width: 900px) {
  .board { grid-template-columns: 1fr; }
  .board__centre { order: 1; }
  .board__left { order: 2; }
  .board__weather { order: 3; }
}

@media (max-width: 640px) {
  .board__tabs {
    display: flex; gap: 0; width: 100%;
    background: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    grid-column: 1 / -1;
  }
  .board__tab {
    flex: 1; min-height: var(--control-h); padding: 0.5rem 0; text-align: center;
    background: none; border: none;
    font-size: 0.88rem; font-weight: 600;
    color: var(--color-text-muted);
    transition: background var(--transition), color var(--transition);
    border-bottom: 2px solid transparent;
  }
  .board__tab--active {
    color: var(--color-accent);
    border-bottom-color: var(--color-accent);
    background: var(--color-bg-secondary);
  }
  .board__panel--hidden { display: none !important; }
}

/* ── Page layouts ────────────────────────────────────────────────────── */
.page-layout {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 1.25rem;
  width: 100%;
  max-width: 1040px;
  margin-inline: auto;
  height: calc(100vh - var(--nav-h) - var(--footer-h) - 3rem);
}

/* Desktop: pin header + add-item, scroll only the item list */
.list-main {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}
.list-content {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
.list-content .item-list--full {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

/* Sidebar body: always visible on desktop */
.sidebar__body { display: contents; }
.sidebar__trigger { display: none; }

/* Desktop: hide mobile-only elements */
.panel-title--picker { display: none; }
.list-picker { display: none; }

@media (max-width: 640px) {
  .page-layout {
    grid-template-columns: 1fr;
    height: calc(100dvh - var(--nav-h) - var(--footer-h) - env(safe-area-inset-bottom, 0px) - 1.2rem);
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .list-main {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .list-content {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .list-content .add-item {
    flex-shrink: 0;
  }

  .list-content .item-list--full {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    min-height: 0;
  }

  /* Mobile: hide sidebar entirely, use inline list-picker instead */
  .sidebar { display: none !important; }
  .panel-title--static { display: none; }
  .panel-title--picker {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    background: none;
    border: none;
    padding: 0;
    font-family: var(--font-heading);
    font-size: 1.25rem;
    line-height: 1.25;
    font-weight: 600;
    color: var(--color-text);
    cursor: pointer;
    flex: 1 1 8rem;
    min-width: 0;
    text-align: left;
  }
  .panel-title__arrow {
    font-size: 0.75rem;
    transition: transform var(--transition);
    opacity: 0.6;
  }
  .panel-title__arrow--open {
    transform: rotate(180deg);
  }

  /* Mobile list picker (controlled by x-show) */
  .list-picker {
    display: block;
    background: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 0.5rem;
    margin-bottom: 0.5rem;
  }
  .list-picker__nav {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 2px;
  }
  .list-picker__item {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    min-height: var(--control-h-sm);
    padding: 0.35rem 0.6rem;
    border-radius: var(--radius-sm);
    background: none;
    border: none;
    font-size: 0.88rem;
    color: var(--color-text);
    cursor: pointer;
    transition: background var(--transition);
  }
  .list-picker__item:hover { background: var(--color-bg-secondary); }
  .list-picker__item--active { background: var(--color-bg-secondary); font-weight: 600; color: var(--color-accent); }
  .list-picker__admin { margin-top: 0.4rem; padding-top: 0.4rem; border-top: 1px solid var(--color-border-light); }

  /* Remove old sidebar mobile styles */
  .sidebar__body {
    display: none;
    background: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 0.75rem;
    margin-top: 0.4rem;
  }
  .sidebar--open .sidebar__body {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }
  .sidebar__nav { flex-direction: row; flex-wrap: wrap; }
  .sidebar__item { width: auto; }
}

.page-narrow {
  max-width: 680px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 1.5rem;
}

/* Every page opens the same way: title on the left, its controls on the
   right, a rule underneath. .page-heading is the plain variant used by the
   narrow pages, .page-header the variant that carries controls. */
.page-header,
.page-heading {
  border-bottom: 2px solid var(--color-border);
  padding-bottom: 0.55rem;
  margin-bottom: 0.85rem;
}
.page-header {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
}
.page-header__title,
.page-heading {
  font-size: 1.5rem; line-height: 1.25;
  color: var(--color-text);
}
.page-header__title { flex: 1 1 12rem; min-width: 0; }
.page-header__actions {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 0.5rem; margin-left: auto;
}
/* Labelled control in a header or toolbar: "Sort [select]" */
.control-label {
  display: inline-flex; align-items: center; gap: 0.4rem;
  color: var(--color-text-muted);
  font-size: 0.78rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.04em;
  white-space: nowrap;
}
.control-label .field__input { width: auto; min-width: 9rem; }

/* Standard lead paragraph under a page header. */
.page-intro {
  color: var(--color-text-secondary);
  font-size: 0.9rem;
  margin-bottom: 1rem;
}
/* Standard "nothing here yet" line. */
.empty-note {
  color: var(--color-text-muted);
  font-size: 0.9rem;
  font-style: italic;
  padding: 0.75rem 0;
}
.empty-note a { color: var(--color-accent); }

@media (max-width: 640px) {
  .page-header__title,
  .page-heading { font-size: 1.25rem; }
  .page-header { gap: 0.4rem 0.5rem; margin-bottom: 0.7rem; }
  .page-header__actions { width: 100%; margin-left: 0; }
  .page-header__actions > .btn:not(.btn--icon) { flex: 1 1 auto; }
  .control-label { flex: 1 1 100%; }
  .control-label .field__input { flex: 1; min-width: 0; }
}

/* ── Panels / Cards ──────────────────────────────────────────────────── */
.board__panel {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-bottom-width: 3px;
  border-radius: var(--radius-lg);
  padding: 1rem;
  box-shadow: var(--shadow-raised);
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}
.board__panel--calendar { position: relative; }
@media (hover: hover) and (pointer: fine) {
  .board__panel:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-raised-hover);
  }
  .board-surface.is-editing > .board__panel:hover {
    transform: none;
  }
}
@media (max-width: 640px) {
  .board { gap: 0.6rem; width: 100%; }
  .board__left { gap: 0.6rem; }
  .board__panel {
    width: 100%;
    border-radius: var(--radius);
    padding: 0.75rem;
  }
  .panel-header { margin-bottom: 0.6rem; }
  .panel-title { font-size: 1.05rem; }
}

.panel-header {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem;
  margin-bottom: 1rem;
}
.panel-title {
  flex: 1;
  font-size: 1.2rem;
  color: var(--color-text);
}
.panel-nav {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--tap); height: var(--tap); flex-shrink: 0;
  background: var(--color-bg-card); border: 1px solid var(--color-border);
  color: var(--color-accent); font-size: 1.35rem; line-height: 1;
  padding: 0; border-radius: var(--radius-sm);
  box-shadow: var(--shadow-control);
  transition: background var(--transition), transform var(--transition), box-shadow var(--transition);
}
.panel-nav:hover { background: var(--color-bg-secondary); }
.panel-nav:active { box-shadow: var(--shadow-control-pressed); transform: translateY(1px); }
.panel-nav--lg { width: 40px; height: 40px; font-size: 1.6rem; }
.panel-footer { margin-top: 0.75rem; text-align: right; font-size: 0.85rem; }

/* ── Sidebar ─────────────────────────────────────────────────────────── */
.sidebar {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-bottom-width: 3px;
  border-radius: var(--radius-lg);
  padding: 1rem;
  height: fit-content;
  box-shadow: var(--shadow-raised);
  position: sticky; top: calc(var(--nav-h) + 1rem);
}
.sidebar__header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 0.75rem;
}
.sidebar__title { font-size: 1rem; }
.sidebar__nav { display: flex; flex-direction: column; gap: 2px; }
.sidebar__item {
  display: flex; align-items: center; gap: 0.4rem;
  width: 100%; min-height: var(--control-h); text-align: left;
  padding: 0.4rem 0.6rem; border-radius: var(--radius-sm);
  background: none; border: none;
  font-size: 0.9rem; color: var(--color-text);
  transition: background var(--transition);
}
.sidebar__item:hover { background: var(--color-bg-secondary); }
.sidebar__item--active { background: var(--color-bg-secondary); font-weight: 600; color: var(--color-accent); }
.sidebar__pin { font-size: 0.8rem; }
.sidebar__new { display: flex; flex-direction: column; gap: 0.4rem; margin-bottom: 0.75rem; }
.sidebar__new-btns { display: flex; gap: 0.4rem; }

/* ── Buttons ─────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.3rem; padding: 0.35rem 1rem;
  min-height: var(--control-h);
  border-radius: var(--radius); border: 1px solid transparent;
  font-size: 0.9rem; font-weight: 500; line-height: 1.2;
  box-shadow: var(--shadow-control);
  transition: background var(--transition), opacity var(--transition), border-color var(--transition), transform var(--transition), box-shadow var(--transition);
  white-space: nowrap;
}
.btn:active:not(:disabled) { transform: translateY(1px); box-shadow: var(--shadow-control-pressed); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; box-shadow: none; }
@media (hover: hover) and (pointer: fine) {
  .btn:hover:not(:disabled),
  .panel-nav:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow-control-hover);
  }
}
.btn--primary { background: var(--color-accent); color: var(--color-on-accent); border-color: var(--color-accent); }
.btn--primary:hover:not(:disabled) { background: var(--color-accent-hover); border-color: var(--color-accent-hover); }
.btn--outline { background: transparent; color: var(--color-accent); border-color: var(--color-accent); }
.btn--outline:hover { background: var(--color-bg-secondary); }
.btn--ghost { background: transparent; color: var(--color-text-secondary); border-color: var(--color-border); }
.btn--ghost:hover { background: var(--color-bg-secondary); }
.btn--danger { background: var(--color-danger); color: var(--color-on-danger); border-color: transparent; }
.btn--danger:hover:not(:disabled) { opacity: 0.88; }
.btn--sm { padding: 0.25rem 0.7rem; min-height: var(--control-h-sm); font-size: 0.82rem; }
.btn--xs { padding: 0.15rem 0.5rem; min-height: var(--control-h-xs); font-size: 0.78rem; }
.btn--full { width: 100%; }
/* Square icon-only button that still meets a comfortable tap target. */
.btn--icon { padding: 0; width: var(--control-h); min-width: var(--control-h); }
.btn--icon.btn--sm { width: var(--control-h-sm); min-width: var(--control-h-sm); }
.link-btn {
  background: none; border: none;
  color: var(--color-accent); font-size: inherit;
  text-decoration: underline; cursor: pointer; padding: 0;
}

/* ── Fields ──────────────────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: 0.25rem; }
.field--grow { flex: 1; }
.field--inline { flex-direction: row; align-items: center; gap: 0.5rem; }
.field__label { font-size: 0.82rem; font-weight: 600; color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.04em; }
.field__input {
  padding: 0.35rem 0.65rem;
  min-height: var(--control-h);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg);
  color: var(--color-text);
  font-size: 0.95rem;
  line-height: 1.35;
  box-shadow: var(--shadow-recessed);
  transition: border-color var(--transition), box-shadow var(--transition);
  width: 100%;
}
.field__input:focus { outline: none; border-color: var(--color-accent); box-shadow: var(--shadow-recessed), 0 0 0 3px var(--color-border-light); box-shadow: var(--shadow-recessed), 0 0 0 3px color-mix(in srgb, var(--color-accent) 20%, transparent); }
.field__input:disabled { opacity: 0.55; cursor: not-allowed; }
.field__input--sm { padding: 0.25rem 0.5rem; min-height: var(--control-h-sm); font-size: 0.85rem; }
.field__input--xs { padding: 0.1rem 0.4rem; min-height: var(--control-h-xs); font-size: 0.78rem; }
/* One dropdown arrow for every select, rather than only those opted in
   via .field__select, which left the app with two select appearances. */
select.field__input,
.field__select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23888' fill='none' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.65rem center;
  padding-right: 2rem;
}
select.field__input--sm {
  background-position: right 0.5rem center;
  padding-right: 1.7rem;
}
.field__textarea { resize: vertical; min-height: 4rem; line-height: 1.5; }
.field__hint { font-size: 0.78rem; color: var(--color-text-muted); }
.field-row { display: flex; gap: 0.75rem; flex-wrap: wrap; }

/* ── Alerts ──────────────────────────────────────────────────────────── */
.alert { padding: 0.65rem 0.9rem; border-radius: var(--radius); font-size: 0.9rem; margin-bottom: 0.5rem; }
.alert--error { background: var(--color-bg-secondary); background: color-mix(in srgb, var(--color-danger) 15%, transparent); border: 1px solid var(--color-danger); color: var(--color-danger); }
.alert--success { background: var(--color-bg-secondary); background: color-mix(in srgb, var(--color-success) 15%, transparent); border: 1px solid var(--color-success); color: var(--color-success); }
.hint { font-size: 0.82rem; color: var(--color-text-muted); }
.hint--success { color: var(--color-success); font-weight: 600; }
.hint--warning { color: var(--color-warning); font-weight: 600; }

/* ── Footer ──────────────────────────────────────────────────────────── */
.footer {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 100;
  height: calc(var(--footer-h) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background: var(--color-nav-bg);
  color: var(--color-nav-text);
  display: flex; align-items: center; justify-content: space-between;
  padding-left: max(1.25rem, env(safe-area-inset-left, 0px));
  padding-right: max(1.25rem, env(safe-area-inset-right, 0px));
  box-shadow: 0 -2px 2px var(--color-shadow-key), 0 -7px 16px var(--color-shadow-ambient);
  font-size: 0.75rem;
}
.footer__version {
  opacity: 0.6;
  font-family: monospace;
  letter-spacing: 0.03em;
  /* Never grows into the links, never shrinks to nothing. */
  flex: 0 0 auto;
}
/* `min-width: 0` is what actually lets the overflow below take effect: without
   it this flex item refuses to shrink past its content, so on a narrow phone
   the links spill over the version label instead of scrolling. */
.footer__links { display: flex; align-items: center; gap: 1rem; min-width: 0; }
.footer__link {
  color: var(--color-nav-text);
  opacity: 0.75;
  background: none; border: none; padding: 0;
  font-size: 0.75rem; cursor: pointer;
  text-decoration: none;
  transition: opacity var(--transition);
}
.footer__link:hover { opacity: 1; text-decoration: underline; }
.footer__push[data-state="enabled"] { color: var(--color-success); }
.footer__push[data-state="partial"],
.footer__push[data-state="disabled"],
.footer__push[data-state="blocked"],
.footer__push[data-state="unavailable"] { color: var(--color-warning, var(--color-nav-text)); }
@media (max-width: 640px) {
  .footer { padding-left: max(0.55rem, env(safe-area-inset-left, 0px)); padding-right: max(0.55rem, env(safe-area-inset-right, 0px)); gap: 0.5rem; }
  /* `flex-start`, not `flex-end`. The row is already pushed right by the
     footer's own `space-between`; aligning its contents to the end as well
     means that once they overflow they spill past the *start* edge, under the
     version label, where they cannot be scrolled back into reach. That hid
     "Edit board", which is the first link and the one that matters here. */
  .footer__links { gap: 0.55rem; overflow-x: auto; justify-content: flex-start; }
  .footer__link { font-size: 0.7rem; flex: 0 0 auto; }
  .footer__version { font-size: 0.68rem; }
}

/* ── Misc ────────────────────────────────────────────────────────────── */
.mt-sm { margin-top: 0.5rem; }
.ws-status { position: fixed; bottom: calc(var(--footer-h) + 0.5rem); right: 1rem; padding: 0.4rem 0.8rem; border-radius: 20px; font-size: 0.78rem; background: var(--color-bg-secondary); border: 1px solid var(--color-border); box-shadow: 0 2px 8px var(--color-shadow); }

/* ── Shared feedback and offline status ─────────────────────────────── */
.kb-offline-banner {
  position: fixed; z-index: 190; top: var(--nav-h); left: 50%; transform: translateX(-50%);
  width: min(100% - 1rem, 720px); padding: 0.45rem 0.75rem;
  display: flex; align-items: center; justify-content: center; gap: 0.45rem;
  border: 1px solid var(--color-warning); border-top: 0;
  border-radius: 0 0 var(--radius) var(--radius);
  background: var(--color-bg-card); background: color-mix(in srgb, var(--color-warning) 18%, var(--color-bg-card));
  color: var(--color-text); box-shadow: 0 3px 10px var(--color-shadow);
  font-size: 0.82rem; font-weight: 600;
}
.kb-offline-banner[hidden] { display: none; }
.kb-toast-region {
  position: fixed; z-index: 260; left: 50%; bottom: calc(var(--footer-h) + env(safe-area-inset-bottom, 0px) + 0.75rem);
  transform: translateX(-50%); width: min(calc(100% - 1rem), 560px); pointer-events: none;
}
.kb-toast {
  display: flex; align-items: center; gap: 0.65rem; min-height: 48px;
  padding: 0.6rem 0.65rem 0.6rem 0.85rem; border-radius: var(--radius);
  border: 1px solid var(--color-border); background: var(--color-nav-bg); color: var(--color-nav-text);
  box-shadow: 0 6px 22px var(--color-shadow); pointer-events: auto;
}
.kb-toast[hidden] { display: none; }
.kb-toast--error { border-color: var(--color-danger); }
.kb-toast--success { border-color: var(--color-success); }
.kb-toast__message { flex: 1; min-width: 0; font-size: 0.88rem; }
.kb-toast__action {
  border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--color-nav-text);
  padding: 0.35rem 0.5rem; font-weight: 700; text-decoration: underline;
}
.kb-toast__action--secondary { opacity: 0.82; }
.kb-toast__close { border: 0; background: transparent; color: var(--color-nav-text); opacity: 0.75; font-size: 1.3rem; padding: 0 0.2rem; }
.kb-dialog-backdrop[hidden] { display: none; }
.kb-dialog__message { white-space: pre-line; }
.kb-choice-list { display: flex; flex-direction: column; gap: 0.35rem; }
.kb-choice-list__item {
  width: 100%; border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  background: var(--color-bg-card); color: var(--color-text); cursor: pointer;
  padding: 0.65rem 0.75rem; text-align: left; font-weight: 600;
}
.kb-choice-list__item:hover, .kb-choice-list__item:focus-visible { background: var(--color-bg-secondary); border-color: var(--color-accent); }
.kb-choice-list__item--selected { border-color: var(--color-accent); border-width: 2px; background: var(--color-bg-secondary); }
.kb-pq-qty { margin-top: 0.65rem; }

/* ── Cached offline launch screen ───────────────────────────────────── */
.offline-shell { overflow-y: auto; overscroll-behavior: auto; }
.offline-page { width: min(100% - 1rem, 660px); margin: 0 auto; padding: max(1rem, env(safe-area-inset-top, 0px)) 0 2rem; }
.offline-page__brand { font-family: var(--font-heading); font-size: 1.4rem; font-weight: 700; color: var(--color-accent); padding: 0.4rem; }
.offline-card { background: var(--color-bg-card); border: 1px solid var(--color-border); border-bottom-width: 3px; border-radius: var(--radius-lg); padding: 1rem; box-shadow: var(--shadow-raised); }
.offline-card h1 { margin: 0.35rem 0; font-size: 1.4rem; }
.offline-card__status { display: inline-flex; align-items: center; gap: 0.35rem; color: var(--color-danger); font-size: 0.8rem; font-weight: 700; text-transform: uppercase; }
.offline-dot { width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--color-danger); }
.offline-card__intro, .offline-card__saved, .offline-card__empty { color: var(--color-text-muted); font-size: 0.84rem; }
.offline-card__intro { margin-bottom: 0.8rem; }
.offline-card__saved { margin: 0.45rem 0; }
.offline-list { margin: 0.5rem 0 1rem; }
.offline-card__actions { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; color: var(--color-warning); font-size: 0.8rem; }

/* Paper pages: one section gap, with headings and their notes kept together. */
.page-narrow { gap: var(--space-section); }
.page-narrow > .page-header,
.page-narrow > .page-heading,
.page-narrow > .card-grid { margin-block: 0; }
.page-header .page-intro { margin: var(--space-control) 0 0; }
.page-header > .stats-section__title { margin: 0; flex: 1; }
.action-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-control);
}
.action-row > .btn { max-width: 100%; white-space: normal; }

/* Preserve the depth cues for people who reduce motion, without moving any
   surface or control toward and away from them. */
@media (prefers-reduced-motion: reduce) {
  .board__panel,
  .card,
  .watch-card,
  .meal-card,
  .btn,
  .panel-nav,
  .chip,
  .inv-pill,
  .staple-chip {
    transition: none;
  }
  .board__panel:hover,
  .card:hover,
  .watch-card:hover,
  .meal-card:hover,
  .btn:hover,
  .btn:active,
  .panel-nav:hover,
  .panel-nav:active,
  .chip:hover,
  .chip:active,
  .inv-pill:hover,
  .inv-pill:active,
  .staple-chip:hover,
  .staple-chip:active {
    transform: none;
  }
}
.field-group {
  min-width: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-card);
  display: flex;
  flex-direction: column;
  gap: var(--space-card);
}
.field-group > legend { padding-inline: var(--space-control); }
.field-stack { display: flex; flex-direction: column; gap: var(--space-control); }
