/* Choreing — layout and typography, shared by both themes.
 *
 * Both theme sheets are always linked (index.html never swaps <link> tags,
 * only the data-theme attribute on <html>), so this file owns geometry only:
 * grids, spacing, sizing, type scale. Every place a colour would go it reads
 * a custom property instead, and retro.css / clean.css each define the whole
 * set. If a property read here is missing, a theme forgot it — this file is
 * not allowed to pick a colour on its own, and tests/css.test.js enforces
 * that by refusing any hex or rgb()/hsl() in here.
 *
 * The nav is a top strip on a desktop-width screen (not a sidebar — this app
 * has three destinations, not a dozen), a bottom tab bar on a phone held
 * upright, and a narrow rail on a phone held sideways. #cal shows the full
 * month grid on a desktop-width screen no matter what; on a phone it shows
 * either a stacked week list or a compact month navigator, switched by
 * #view-switch and read off #cal[data-mode].
 */

/* ============================== Foundations ============================== */

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

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

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
}

body {
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.45;
  color: var(--text);
  background-color: var(--bg);
  overflow-x: hidden;
}

h1, h2, h3, h4, p, ul, ol, dl, dd, figure, fieldset {
  margin: 0;
}

ul, ol {
  list-style: none;
  padding: 0;
}

fieldset {
  border: 0;
  padding: 0;
  min-inline-size: 0;
}

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

img { max-width: 100%; }

button, input, select, textarea {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  color: inherit;
}

/* Every control is a touch target before it is anything else, and a bare
   <select> in the demo bar is as much a control as one inside a .field-row.
   The checkbox and radio exceptions are two rules further down: those are
   glyphs, and their <label> is what the finger actually lands on. */
input, select, textarea {
  min-height: 44px;
}

textarea { resize: vertical; }

h1 { font-size: 1.6rem; line-height: 1.2; }
h2 { font-size: 1.15rem; line-height: 1.25; }
h3 { font-size: 1rem; line-height: 1.3; }

/* The shape of the ring lives here so it survives a theme switch; each theme
   supplies only --focus. Every interactive control in the markup is one of
   these tags, which is what makes one rule enough. */
:is(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

/* ================================ Motion ==================================
 * Structure, not colour: durations and easings are tokens from
 * css/kit/motion.css, so this is the same rule in every theme (clean-theme
 * plan, section 5). Retro's own one-off animations (the starfield twinkle)
 * stay in retro.css; motion.css's reduced-motion rule covers all of it.
 */

a,
button,
.button,
input,
select,
textarea,
.nav-link,
.seg-btn,
.chore-card,
.week-list-item,
.week-row,
.month-nav-day,
.today-item,
.member-row,
.sched-day,
.template-btn {
  transition: background-color var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard),
    border-color var(--duration-fast) var(--ease-standard),
    box-shadow var(--duration-fast) var(--ease-standard),
    transform var(--duration-fast) var(--ease-standard);
}

button:active:not([disabled]),
.button:active:not([disabled]),
.nav-link:active,
.seg-btn:active,
.chore-pref:active,
.color-btn:active,
.week-item-pin:active,
.week-item-done:active {
  transform: scale(0.98);
}

@media (hover: hover) {
  .chore-card:hover,
  .week-list-item:hover,
  .template-btn:hover {
    box-shadow: var(--shadow-2);
  }
}

/* A view becoming visible (a hash-route change swaps which .view is not
   hidden). */
.view:not([hidden]) {
  animation: wp-enter var(--duration) var(--ease-out);
}

.toast:not([hidden]) {
  animation: wp-toast-in var(--duration) var(--ease-out);
}

/* The app toggles whole sections with the `hidden` attribute rather than a
   class, so this has to out-rank every display value either theme sets. */
[hidden] { display: none !important; }

/* The standard visually-hidden pattern: still in the accessibility tree and
   still focusable, just not painted. */
.sr-only {
  position: absolute;
  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;
}

.sr-only:is(input, select, textarea, button) {
  width: 44px;
  height: 44px;
  margin: 0;
  pointer-events: none;
}

input[type="checkbox"],
input[type="radio"] {
  width: auto;
  min-height: 0;
  accent-color: var(--accent);
}

/* ============================== The shell ================================
 * The six sizing constants below are structural, not theme colours, and the
 * same in every variant — so they live on :root (not #app, where they used
 * to sit) to satisfy the shared token contract's tokenProblems() check,
 * which only resolves var() against root-scoped custom properties.
 */

:root {
  --topbar-h: 3.5rem;
  --navbar-h: 3.25rem;
  --tabbar-h: 3.75rem;
  --rail-w: 4.5rem;
  --gutter: 1.25rem;
}

#app {
  /* Gives back the height of the site-wide header bar above #app
     (willperlak.com's /site-nav/, not sticky), so a short page doesn't
     scroll by that much. nav.css publishes it; the fallback 0 is right when
     it isn't loaded (run locally, the bar is absent). */
  min-height: calc(100dvh - var(--wp-site-nav-h, 0px));
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto auto auto minmax(0, 1fr);
  grid-template-areas:
    "topbar"
    "nav"
    "banner"
    "demo"
    "main";
}

#topbar {
  grid-area: topbar;
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  min-height: var(--topbar-h);
  padding: 0.35rem max(var(--gutter), env(safe-area-inset-right)) 0.35rem max(var(--gutter), env(safe-area-inset-left));
  padding-top: calc(0.35rem + env(safe-area-inset-top));
}

#brand {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 1.4rem;
  font-weight: bold;
  letter-spacing: 0.02em;
  text-decoration: none;
}

.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.3rem;
  font-size: 0.7rem;
  font-weight: bold;
  line-height: 1;
}

/* A full-width block, not a toast — it sits in the shell's own grid row and
   stays on screen until the condition it reports clears. */
#unavailable-banner,
.banner {
  grid-area: banner;
  width: 100%;
  padding: 0.6rem var(--gutter);
  font-size: 0.9rem;
  font-weight: bold;
  text-align: center;
}

#demo-bar {
  grid-area: demo;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem 0.75rem;
  padding: 0.4rem max(var(--gutter), env(safe-area-inset-right)) 0.4rem max(var(--gutter), env(safe-area-inset-left));
  font-size: 0.85rem;
}

#demo-user {
  min-width: 0;
  max-width: 14rem;
}

#demo-note {
  min-width: 0;
  flex: 1 1 12rem;
  font-size: 0.8rem;
}

/* ================================= Nav ====================================
 * Default (desktop-width) shape: a horizontal strip under the topbar, three
 * destinations wide. Compact widths and landscape override this below.
 */

#nav {
  grid-area: nav;
  position: sticky;
  top: var(--topbar-h);
  z-index: 25;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.4rem;
  min-height: var(--navbar-h);
  padding: 0.4rem max(var(--gutter), env(safe-area-inset-right)) 0.4rem max(var(--gutter), env(safe-area-inset-left));
}

.nav-link {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  padding: 0.4rem 0.9rem;
  text-decoration: none;
  font-size: 0.95rem;
}

.nav-icon {
  flex: none;
  width: 1.4rem;
  height: 1.4rem;
}

.nav-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.icon {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  vertical-align: -0.2em;
}

/* Loading has nothing to navigate to yet, and an invalid session has nowhere
   safe to send the tap. */
#app[data-screen="loading"] #nav,
#app[data-screen="unavailable"] #nav,
#app[data-screen="unavailable"] #main {
  display: none;
}

/* ================================= Main =================================== */

#main {
  grid-area: main;
  min-width: 0;
  padding: var(--gutter) max(var(--gutter), env(safe-area-inset-right)) 4rem max(var(--gutter), env(safe-area-inset-left));
}

.view {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-width: 68rem;
  min-width: 0;
}

.view-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
}

.view-title {
  font-size: 2.1rem;
  font-weight: bold;
  line-height: 1.1;
  letter-spacing: -0.01em;
  min-width: 0;
  overflow-wrap: anywhere;
}

.muted { font-size: 0.9rem; }

.empty {
  padding: 1.5rem 1rem;
  text-align: center;
  font-size: 0.95rem;
}

/* ================================ Panels ================================= */

.panel {
  padding: 1rem 1.1rem;
  border-radius: var(--radius);
  min-width: 0;
}

.panel > * + * { margin-top: 0.75rem; }

.profile-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.35rem;
}

.profile-app-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  /* A short label ("Friends") in a narrow fallback font measured 42px wide. */
  min-width: 44px;
  text-decoration: none;
  font-size: 0.9rem;
}

/* ================================ Forms ================================== */

.field-row {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

.field-row > label,
.field-label {
  font-size: 0.82rem;
  font-weight: bold;
  letter-spacing: 0.01em;
}

.field-row input,
.field-row select,
.field-row textarea {
  width: 100%;
  min-width: 0;
  min-height: 44px;
  padding: 0.55rem 0.7rem;
  border-radius: var(--radius-sm);
}

.field-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: 0.75rem;
  min-width: 0;
}

.checkbox-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 44px;
  cursor: pointer;
}

.checkbox-row input {
  width: auto;
  min-width: 0;
  max-width: none;
  min-height: 0;
  flex: none;
  margin: 0;
}

.errors {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
}

.form-actions,
.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

button,
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-height: 44px;
  min-width: 44px;
  padding: 0.5rem 1rem;
  border-radius: var(--radius-sm);
  font-size: 0.95rem;
  text-decoration: none;
  cursor: pointer;
}

.primary,
.danger {
  font-weight: bold;
}

.link-btn {
  min-height: 44px;
  padding: 0.25rem 0;
  text-decoration: underline;
  cursor: pointer;
  background: none;
  border: 0;
}

/* =========================== Segmented control =========================== */

.segmented {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  padding: 0.2rem;
  border-radius: var(--radius-sm);
}

.seg-btn {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
  padding: 0.4rem 0.7rem;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  text-align: center;
  white-space: nowrap;
  cursor: pointer;
}

/* ================================ Avatars ================================ */

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  overflow: hidden;
  font-weight: bold;
  font-size: 0.85rem;
  line-height: 1;
  text-transform: uppercase;
  user-select: none;
}

.avatar-small {
  width: 1.75rem;
  height: 1.75rem;
  font-size: 0.65rem;
}

.avatar-large {
  width: 6rem;
  height: 6rem;
  font-size: 2rem;
}

.avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}

.avatar-initials { line-height: 1; }

/* ================================= Toast ================================= */

.toast {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(1.25rem + env(safe-area-inset-bottom));
  z-index: 100;
  max-width: min(92vw, 30rem);
  padding: 0.7rem 1.1rem;
  border-radius: var(--radius);
  text-align: center;
  font-weight: bold;
}

/* ================================ Chores ================================== */

.chore-card {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 0.8rem 0.9rem;
  border-radius: var(--radius);
  min-width: 0;
}

.chore-swatch {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  margin-top: 0.15rem;
  border-radius: var(--radius-sm);
}

.chore-card-body {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  flex: 1 1 auto;
  min-width: 0;
}

.chore-card-title {
  font-size: 1.05rem;
  font-weight: bold;
  overflow-wrap: anywhere;
  /* A link is a target: 44px tall on a phone (Chromium audit). */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.chore-card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.15rem 0.75rem;
  font-size: 0.85rem;
}

.chore-card-members {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.chore-card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.2rem;
}

.chore-pref {
  font-size: 0.85rem;
  padding: 0.3rem 0.65rem;
}

.template-btn {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.2rem;
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius-sm);
  text-align: left;
  min-width: 0;
  min-height: 44px;
}

/* ================================ Wizard ================================== */

#wizard-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.wizard-step {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0.2rem 0.6rem;
  border-radius: var(--radius-sm);
  font-size: 0.78rem;
  font-weight: bold;
}

.wizard-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem;
}

.repeat-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.repeat-row input[type="number"] {
  width: 5rem;
  min-width: 0;
}

.color-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0.5rem;
  max-width: 20rem;
}

.color-btn {
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border-radius: var(--radius-sm);
}

.color-btn[aria-pressed="true"] {
  outline-offset: 2px;
}

.member-pick {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.member-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 44px;
  padding: 0.25rem 0.4rem;
  border-radius: var(--radius-sm);
  min-width: 0;
}

/* =========================== Schedule editor ============================= */

#schedule-editor,
.sched-grid {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  container-type: inline-size;
}

.sched-week {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.4rem;
}

/* The whole-week presets the vendored editor puts above the weeks
 * (Scheduler FEAT-scheduler-1, vendored at 34a1601). */
.sched-presets {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.25rem;
}

.sched-presets-label {
  font-size: 0.8125rem;
  font-weight: 600;
}

.sched-preset {
  font-size: 0.8125rem;
}

.sched-day {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
  min-height: 5.5rem;
  padding: 0.4rem;
  border-radius: var(--radius-sm);
}

.sched-day-name,
.sched-day-label {
  font-size: 0.75rem;
  font-weight: bold;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sched-day-toggle {
  width: auto;
  min-height: 0;
  flex: none;
  margin: 0;
  cursor: pointer;
}

.sched-day-empty {
  font-size: 0.72rem;
}

.sched-intervals {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.sched-interval {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0.2rem 0.3rem;
  padding: 0.25rem 0.3rem;
  border-radius: var(--radius-sm);
  font-size: 0.75rem;
}

.sched-time-label,
.sched-interval-time {
  font-size: 0.68rem;
}

.sched-interval input[type="time"] {
  width: 100%;
  min-width: 0;
  max-width: none;
  min-height: 2rem;
  padding: 0.15rem 0.25rem;
  font-size: 0.78rem;
}

.sched-interval input[type="time"]::-webkit-calendar-picker-indicator {
  display: none;
}

.sched-interval .sched-remove-window {
  grid-column: 1 / -1;
}

.sched-add-window,
.sched-copy,
.sched-remove-window {
  width: 100%;
  min-width: 0;
  min-height: 2rem;
  padding: 0.25rem 0.4rem;
  font-size: 0.72rem;
  border-radius: var(--radius-sm);
}

.check-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 44px;
  padding: 0.25rem 0.4rem;
  border-radius: var(--radius-sm);
  min-width: 0;
}

.check-row input {
  width: auto;
  min-height: 0;
  flex: none;
  margin: 0;
}

.check-row label {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  min-height: 44px;
  cursor: pointer;
}

@container (max-width: 880px) {
  .sched-week { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
}

/* ============================== Schedule view =============================
 * #cal always shows the full month grid at desktop widths; below the
 * compact breakpoint it shows either .week-rows or .month-nav, switched by
 * #view-switch and read off #cal[data-mode].
 */

#view-schedule {
  align-items: start;
}

.cal-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
}

.cal-nav {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

#cal-prev,
#cal-next,
#cal-today {
  flex: none;
  min-width: 2.75rem;
  padding: 0.3rem 0.6rem;
  font-size: 1.1rem;
  line-height: 1;
}

#cal-label {
  flex: 1 1 auto;
  min-width: 0;
  text-align: center;
  font-size: 1.05rem;
  font-weight: bold;
}

/* The full desktop month grid. */
.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.25rem;
}

.cal-weekday {
  text-align: center;
  font-size: 0.72rem;
  font-weight: bold;
  padding: 0.25rem 0;
  min-width: 0;
}

.cal-week {
  display: contents;
}

.cal-day {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
  min-height: 96px;
  padding: 0.3rem;
  border-radius: var(--radius-sm);
  text-align: left;
  cursor: pointer;
}

.cal-day-number {
  font-size: 0.85rem;
  font-weight: bold;
}

.cal-banners {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
  flex: 1 1 auto;
}

/* A block, not a pill: it wraps and clamps rather than truncating to one
   line, because a chore's title is the whole point of the banner. */
.cal-banner {
  position: relative;
  display: block;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  overflow-wrap: anywhere;
  padding: 0.2rem 1.2rem 0.2rem 0.4rem;
  border-radius: var(--radius-sm);
  font-size: 0.72rem;
  line-height: 1.25;
  text-align: left;
  min-width: 0;
}

.cal-day[data-banners="3"] .cal-banner { -webkit-line-clamp: 2; }
.cal-day[data-banners="4"] .cal-banner { -webkit-line-clamp: 1; }

.cal-banner-done {
  text-decoration: line-through;
  opacity: 0.4;
}

.cal-banner-unpin {
  position: absolute;
  top: 0;
  right: 0;
  width: 1.2rem;
  min-width: 0;
  min-height: 0;
  height: 100%;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: inherit;
  font-size: 0.85rem;
  line-height: 1;
}

.cal-more {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 22px;
  padding: 0.1rem 0.4rem;
  border-radius: var(--radius-sm);
  font-size: 0.68rem;
  font-weight: bold;
  align-self: flex-start;
}

/* ------------------------------ Phone: week ------------------------------- */

.week-rows {
  display: none;
  flex-direction: column;
  gap: 0.4rem;
}

.week-row {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.5rem 0.6rem;
  border-radius: var(--radius-sm);
  min-width: 0;
}

.week-row-date {
  flex: none;
  width: 3rem;
  font-size: 0.85rem;
  font-weight: bold;
  text-align: center;
}

.week-row-banners {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  flex: 1 1 auto;
  min-width: 0;
}

/* ----------------------------- Phone: month ------------------------------- */

.month-nav {
  display: none;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 2px;
}

.month-nav-day {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.2rem;
  width: 100%;
  min-width: 0;
  padding-inline: 0;
  min-width: 0;
  min-height: 44px;
  padding: 0.3rem 0.15rem;
  border-radius: var(--radius-sm);
  font-size: 0.8rem;
}

.cal-bars {
  display: flex;
  gap: 0.12rem;
  min-height: 4px;
}

.cal-bar {
  width: 0.6rem;
  height: 4px;
  border-radius: var(--radius-sm);
}

.cal-count {
  font-size: 0.6rem;
  font-variant-numeric: tabular-nums;
}

/* ------------------------------ View switch ------------------------------- */

#view-switch {
  display: none;
}

/* min-width/max-width: the chips are nowrap, and without them a full strip
   widens its grid or flex track instead of scrolling inside itself, and the
   whole phone page scrolls sideways (UX-choreing-9). */
#today-strip {
  display: none;
  gap: 0.5rem;
  overflow-x: auto;
  padding-bottom: 0.2rem;
  min-width: 0;
  max-width: 100%;
}

.today-item {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.3rem 0.7rem;
  border-radius: var(--radius-sm);
  font-size: 0.82rem;
  white-space: nowrap;
}

.today-done {
  text-decoration: line-through;
  opacity: 0.55;
}

/* The strip's visible "Today" heading: phone only, like the strip. */
.today-label {
  display: none;
}

/* The chip's open circle or tick, so done is not only a style. */
.today-check {
  margin-right: 0.35rem;
  /* inline-block stops a done chip's line-through reaching the tick. */
  display: inline-block;
  text-decoration: none;
}

/* ------------------------- Today (the landing view) ------------------------ */

#today-list,
#today-earlier {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* The empty line's link to Schedule is a tap target like any button. */
#today-empty a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

#today-earlier-title {
  margin-top: 1.2rem;
  font-size: 1.05rem;
}

.today-row .week-item-title {
  font-size: 1.05rem;
}

/* The big one-tap Done: the whole point of the screen on a phone. */
.today-toggle {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  min-width: 7rem;
  padding: 0.4rem 1rem;
  font-size: 1rem;
  font-weight: bold;
}

.today-toggle:active:not([disabled]) {
  transform: scale(0.98);
}

/* -------------------------------- Week list -------------------------------- */

#week-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

/* The Household board (views/household.js): the week's rows grouped under a
   heading per day, the same row look as the week list. */
#household-list,
.household-rows {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-width: 0;
}

.household-day {
  margin: 0.6rem 0 0;
  font-size: 1rem;
}

#household-prev,
#household-next,
#household-today {
  flex: none;
  min-width: 2.75rem;
  min-height: 44px;
  padding: 0.3rem 0.6rem;
  font-size: 1.1rem;
  line-height: 1;
}

#household-label {
  flex: 1 1 auto;
  min-width: 0;
  text-align: center;
  font-size: 1.05rem;
  font-weight: bold;
}

#household-fair {
  margin-top: 1rem;
}

/* The Overdue list at the top of Schedule (FEAT-choreing-7) and of Today
   (RCH2-10). */
#today-overdue {
  margin-bottom: 1rem;
}

#overdue-list,
#today-overdue-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-width: 0;
}

.overdue-item {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.3rem 0.6rem;
  padding: 0.55rem 0.7rem;
  border-radius: var(--radius-sm);
  min-width: 0;
}

.overdue-text {
  flex: 1 1 12rem;
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: bold;
}

.overdue-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.overdue-done,
.overdue-dismiss {
  min-height: 44px;
}

.week-list-item {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.3rem 0.6rem;
  padding: 0.55rem 0.7rem;
  border-radius: var(--radius-sm);
  min-width: 0;
}

.week-item-title {
  flex: 1 1 12rem;
  min-width: 0;
  font-weight: bold;
  overflow-wrap: anywhere;
}

.week-item-meta {
  font-size: 0.82rem;
}

.week-item-count {
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
}

.week-item-why {
  flex: 1 1 100%;
  font-size: 0.76rem;
}

.week-item-actions {
  flex-basis: 100%;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem 0.6rem;
}

.week-item-credit {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.82rem;
  min-width: 0;
}

.week-item-credit select {
  min-height: 44px;
  max-width: 11rem;
}

.week-item-pin,
.week-item-random,
.week-item-done {
  flex: none;
  min-height: 44px;
  padding: 0.3rem 0.7rem;
  font-size: 0.82rem;
}

.is-placing {
  outline: 2px dashed currentColor;
  outline-offset: 2px;
}

#pin-status {
  font-size: 0.82rem;
}

.fair-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.3rem 0;
}

.fair-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fair-count {
  flex: none;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
}

/* ============================ Compact widths ============================
 * Under 900px #cal switches from the always-on month grid to whichever of
 * .week-rows / .month-nav matches #cal[data-mode], and the two-column
 * schedule layout collapses to one column.
 */

@media (max-width: 899px) {
  #view-switch {
    display: flex;
  }

  #today-strip {
    display: flex;
  }

  .today-label {
    display: block;
  }

  .cal-grid {
    display: none;
  }

  /* #cal is a flex item of .view with no explicit width; without this its
     own width falls back to its content's max-content size rather than
     stretching to fill .view, so .month-nav's `repeat(7, minmax(0, 1fr))`
     had nothing real to divide and each column sized to its widest glyph
     instead (retro's Comic Sans ~27px, clean's system font ~22px — review
     N2: clean's cells were 3px narrower than retro's only because of this).
     width: 100% gives #cal a definite width, so every column comes out the
     same real ~50px in both themes, comfortably past the 44px target. */
  #cal { width: 100%; }

  #cal[data-mode="week"] .week-rows {
    display: flex;
  }

  #cal[data-mode="month"] .month-nav {
    display: grid;
  }
}

/* ============================== Compact widths (700px) ==================== */

@media (max-width: 700px) {
  #app {
    --gutter: 1rem;
  }

  #nav {
    position: fixed;
    inset: auto 0 0 0;
    top: auto;
    z-index: 40;
    justify-content: space-around;
    padding: 0.2rem max(0.2rem, env(safe-area-inset-right)) 0 max(0.2rem, env(safe-area-inset-left));
    padding-bottom: env(safe-area-inset-bottom);
  }

  .nav-link {
    flex: 1 1 0;
    flex-direction: column;
    justify-content: center;
    gap: 0.1rem;
    min-width: 0;
    min-height: 44px;
    padding: 0.3rem 0.15rem;
  }

  .nav-text {
    font-size: 0.62rem;
    line-height: 1.1;
    max-width: 100%;
  }

  #main {
    padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  }

  .toast {
    bottom: calc(var(--tabbar-h) + 0.75rem + env(safe-area-inset-bottom));
  }

  .view-title { font-size: 1.75rem; }

  .field-grid { grid-template-columns: minmax(0, 1fr); }

  .panel { padding: 0.85rem 0.9rem; }

  .sched-interval input[type="time"] {
    min-height: 44px;
    font-size: 1rem;
  }

  /* Below the width the full month grid gives way to the stacked phone
     views, a banner is read with a thumb, not a cursor. */
  .cal-banner {
    min-height: 44px;
  }

  .sched-day-label {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
}

/* ============================ Phone landscape =============================
 * 390px of height with a keyboard up is nothing. Nav becomes a narrow left
 * rail of icons instead of a bottom bar, so the keyboard never fights it.
 */

@media (orientation: landscape) and (max-height: 500px) {
  #app {
    grid-template-columns: calc(var(--rail-w) + env(safe-area-inset-left, 0px)) minmax(0, 1fr);
    grid-template-rows: auto auto auto minmax(0, 1fr);
    grid-template-areas:
      "topbar topbar"
      "banner banner"
      "demo   demo"
      "nav    main";
  }

  #demo-bar { grid-area: demo; }

  #nav {
    position: static;
    flex-direction: column;
    justify-content: flex-start;
    gap: 0.2rem;
    padding: 0.4rem 0.25rem;
    padding-left: calc(0.25rem + env(safe-area-inset-left, 0px));
    min-height: 0;
  }

  .nav-link {
    flex-direction: column;
    justify-content: center;
    gap: 0.1rem;
    padding: 0.35rem 0.1rem;
    text-align: center;
    width: 100%;
    min-width: 44px;
    margin-inline: 0;
  }

  .nav-text {
    font-size: 0.6rem;
    line-height: 1.05;
    white-space: normal;
    overflow: visible;
  }

  #topbar { min-height: 3rem; padding-left: max(1rem, env(safe-area-inset-left, 0px)); padding-right: max(1rem, env(safe-area-inset-right, 0px)); }
  #main { padding-right: max(1rem, env(safe-area-inset-right, 0px)); }
  .view-title { font-size: 1.6rem; }

  .sched-interval input[type="time"] {
    min-height: 44px;
    font-size: 1rem;
  }
}

/* The page-wide reduced-motion rule lives once in css/kit/motion.css and
   covers every animation and transition here too. */

/* ========================= Desktop schedule layout ========================= */

@media (min-width: 900px) {
  /* Two columns: the calendar (toolbar above it) on the left, spanning every
     row the right column needs; the week's list, status and fair-share panel
     stacked on the right. The header row spans both. */
  #view-schedule {
    display: grid;
    grid-template-columns: minmax(0, 62%) minmax(0, 1fr);
    grid-template-rows: auto auto repeat(5, auto) minmax(0, 1fr);
    column-gap: 1.25rem;
    row-gap: 0.6rem;
    align-items: start;
    align-content: start;
  }

  #view-schedule > .view-header:first-child {
    grid-column: 1 / -1;
    grid-row: 1;
  }

  .cal-toolbar {
    grid-column: 1;
    grid-row: 2;
  }

  #cal {
    grid-column: 1;
    grid-row: 3 / span 6;
    min-width: 0;
  }

  #today-strip {
    grid-column: 1;
    grid-row: 9;
  }

  #view-schedule > .view-header:not(:first-child) { grid-column: 2; grid-row: 2; }
  #overdue { grid-column: 2; grid-row: 3; }
  #week-empty { grid-column: 2; grid-row: 4; }
  #week-list { grid-column: 2; grid-row: 5; }
  #pin-status { grid-column: 2; grid-row: 6; }
  #week-fair { grid-column: 2; grid-row: 7; }

  /* The × on a banner is a hover affordance on a pointer device; the list's
     controls do the same job. It stays in the tree for keyboard users. */
  .cal-grid .cal-banner-unpin {
    opacity: 0;
  }
}

@media (max-width: 899px) {
  .cal-banner { padding-right: 2.6rem; min-height: 44px; }
  .cal-banner-unpin { width: 2.75rem; min-height: 44px; }
  .wizard-step { min-height: 44px; }
  .cal-grid .cal-banner:hover .cal-banner-unpin,
  .cal-grid .cal-banner:focus-within .cal-banner-unpin {
    opacity: 1;
  }
}

/* Native date and time controls: never narrower than their value. */
input[type="date"],
input[type="time"] {
  min-width: 0;
  padding-right: 0.4rem;
}

.availability-hint {
  margin: 0 0 0.5rem;
  font-size: 0.9rem;
}

/* Away dates on Profile (FEAT-choreing-4): one row per range, Remove at the end. */
#away-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.away-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.away-remove {
  font-size: 0.9rem;
}

/* Week rows on the phone are the reading view: banners get real height and
   readable type there, unlike the dense month grid. */
.week-row .cal-banner {
  min-height: 3rem;
  font-size: 0.95rem;
  padding: 0.5rem 2.6rem 0.5rem 0.6rem;
  -webkit-line-clamp: 3;
}
.week-item-credit-toggle {
  min-height: 44px;
  font-size: 0.82rem;
}

.chore-last-done {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.85rem;
}

.fair-how {
  font-size: 0.85rem;
  margin: 0 0 0.5rem;
}
#availability-note {
  margin: 0.2rem 0 0.6rem;
}
/* The weekly budget warning (FEAT-choreing-13): laid out like the note
   above it; its colour is the theme's --danger (retro.css, clean.css). */
.budget-warn {
  margin: 0.2rem 0 0.6rem;
}
#availability-note a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* ---------------------------- Signed-out landing --------------------------- */
/* server/landing.js; layout only, the colours are the shared .button rules. */

.landing {
  max-width: 36rem;
  margin: 2rem auto;
  padding: 0 1rem;
}

.landing-actions {
  margin-top: 1.5rem;
}
