/* styles.css — mobile-first, one-handed layout, system light/dark mode */

:root {
  --bg: #f5f7f6;
  --surface: #ffffff;
  --text: #12201d;
  --text-muted: #5b6b67;
  --primary: #1c645c;
  --primary-contrast: #ffffff;
  --accent: #ffb03b;
  --danger: #b3432b;
  --border: #dde5e2;
  --warning-bg: #fff3e0;
  --warning-text: #8a4a00;
  --radius: 14px;

  /* Progress grid status colors (feature 3 grid) */
  --day-good: #3f8f3f;
  --day-mid: #b8790f;
  --day-bad: #b3432b;
  --cell-full-bg: #cfe8b0;
  --cell-full-border: #3f7a1f;
  --cell-full-icon: #2c5a16;
  --cell-two-border: #3f7a1f;
  --cell-missed-bg: #e4e2da;
  --cell-future-bg: #eeece4;
  --cell-today-bg: #d7e8fb;

  /* Identity contribution history (v1j, H1+H2) — fixed rotation of 12
     distinct hues, one per identity; habits within an identity are
     distinguished via fill-opacity on the SAME variable (see
     history-ui.js), not a second color axis. Extended from 6 to 12
     ("klein", 2026-09-19) so a 7th+ identity gets its own unique color
     instead of repeating identity-1 — identities 1-6 are unchanged, so
     anyone with 6 or fewer identities sees no visual difference. */
  --identity-1: #1c645c;
  --identity-2: #b3432b;
  --identity-3: #2a5d9c;
  --identity-4: #6a4c9c;
  --identity-5: #b8790f;
  --identity-6: #a13d6f;
  --identity-7: #7b962c;
  --identity-8: #2c9646;
  --identity-9: #2c8396;
  --identity-10: #2c3396;
  --identity-11: #8c2c96;
  --identity-12: #962c41;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f1a19;
    --surface: #172624;
    --text: #eef3f1;
    --text-muted: #a3b3af;
    --primary: #4fb3a4;
    --primary-contrast: #072320;
    --accent: #ffb03b;
    --danger: #ff8b6d;
    --border: #24413c;
    --warning-bg: #2c2210;
    --warning-text: #ffca80;

    --day-good: #6fc45a;
    --day-mid: #e0a640;
    --day-bad: #e2836c;
    --cell-full-bg: #234a17;
    --cell-full-border: #6fc45a;
    --cell-full-icon: #a9e08f;
    --cell-two-border: #6fc45a;
    --cell-missed-bg: #263330;
    --cell-future-bg: #16211f;
    --cell-today-bg: #163554;

    --identity-1: #4fb3a4;
    --identity-2: #e2836c;
    --identity-3: #6ea8e0;
    --identity-4: #b39ddb;
    --identity-5: #e0a640;
    --identity-6: #d98bb3;
    --identity-7: #a3ba5e;
    --identity-8: #5eba75;
    --identity-9: #5ea9ba;
    --identity-10: #5e64ba;
    --identity-11: #b15eba;
    --identity-12: #ba5e71;
  }
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  -webkit-tap-highlight-color: transparent;
}

body {
  min-height: 100vh;
  padding-bottom: 96px; /* room for the FAB, keeps content reachable */
}

/* Capped width so the app doesn't stretch full-bleed on a desktop browser
   during local testing — it's still 100% width (and unaffected) on an
   actual phone screen. */
.app-shell {
  max-width: 480px;
  margin: 0 auto;
}

/* Icon row on top, title below (not side-by-side) — 7 icon buttons at the
   accessibility-driven 44px min-width each (see button base rule below)
   need ~332px alone, which left no room for the title on the same line
   and forced the page wider than the viewport on narrower phones
   (reported: horizontal overflow on a 360px-wide screen). column-reverse
   keeps DOM order (h1 first) so screen readers still meet the title
   before the action toolbar, while visually the icons render first. */
.app-header {
  padding: 20px 16px 8px;
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: 6px;
}

.app-header h1 {
  margin: 0;
  font-size: 1.4rem;
}

.btn-icon-header {
  background: transparent;
  color: var(--text-muted);
  font-size: 1.3rem;
  padding: 0;
  flex-shrink: 0;
}

.header-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px;
  width: 100%;
}

.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;
}

.section-heading {
  margin: 4px 16px 0;
  font-size: 0.95rem;
  color: var(--text-muted);
  font-weight: 600;
}

.habit-list {
  padding: 8px 16px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.empty-state {
  color: var(--text-muted);
  text-align: center;
  margin-top: 15vh;
  padding: 0 24px;
  line-height: 1.5;
}

/* ---- Habit card ---- */

.habit-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
}

.habit-identity {
  margin: 0 0 2px;
  font-size: 0.85rem;
  color: var(--text-muted);
  font-style: italic;
}

.habit-name {
  margin: 0 0 4px;
  font-size: 1.1rem;
}

.habit-meta {
  margin: 0;
  font-size: 0.82rem;
  color: var(--text-muted);
}

/* ---- Temptation bundling chain (H8, 2nd Law) ---- */

.habit-chain {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}

.habit-chain:not(:empty) {
  margin: 2px 0 6px;
}

.chain-badge {
  font-size: 0.78rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 3px 8px;
  color: var(--text-muted);
}

.chain-badge-habit {
  color: var(--text);
  font-weight: 600;
}

.chain-badge-reward {
  background: var(--warning-bg);
  border-color: var(--accent);
  color: var(--warning-text);
}

/* Motivation ritual (H10, p.129-130, 2nd Law) — a pleasant cue BEFORE the
   habit, as opposed to the reward badge above (AFTER). Reuses the plain
   chain-badge shape, distinguished only via the primary color (already
   the app's "positive/forward" token) rather than introducing a new
   background token. */
.chain-badge-ritual {
  border-color: var(--primary);
  color: var(--primary);
}

.chain-arrow {
  color: var(--text-muted);
  font-size: 0.75rem;
  flex-shrink: 0;
}

/* ---- Benefits / reframing (H10, p.131-132) ---- */
/* A plain bulleted list, deliberately not boxed like .chain-badge-reward
   or .habit-warning — this is the habit's own, self-generated payoff, not
   an external reward or a failure state, so it stays visually quiet. */

.habit-benefits {
  margin: 2px 0 6px;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.habit-benefits li {
  font-size: 0.82rem;
  color: var(--text-muted);
  padding-left: 18px;
  position: relative;
}

.habit-benefits li::before {
  content: '✨';
  position: absolute;
  left: 0;
  font-size: 0.75rem;
}

/* ---- Environment design toggle (H6, 1st Law) ---- */
/* One-time confirmation, not a daily control — see docs/PRODUCT.md for why
   this stays a plain toggle rather than an active reminder. */

.habit-env-toggle {
  display: block;
  width: 100%;
  min-height: 44px;
  margin: 6px 0 0;
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--bg);
  border: 1px dashed var(--border);
  color: var(--text-muted);
  font-size: 0.82rem;
  text-align: left;
}

.habit-env-toggle.is-done {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--day-good);
}

.habit-warning {
  margin: 8px 0 0;
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--warning-bg);
  color: var(--warning-text);
  font-size: 0.82rem;
}

/* ---- Goldilocks level-up banner (H19) ---- */
/* Positive/motivational, not a failure warning like .habit-warning above —
   reuses the existing --day-good token instead of the amber warning tokens
   so the two read as clearly different in tone. Persistent (recomputed on
   every render from the live streak), not a one-time dismissible toast:
   see docs/DATAMODEL.md. */

.habit-levelup-banner {
  margin: 8px 0 0;
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--bg);
  border: 1px solid var(--day-good);
  color: var(--day-good);
  font-size: 0.82rem;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.habit-levelup-banner .habit-levelup-text {
  flex: 1 1 140px;
}

.habit-levelup-btn {
  background: var(--day-good);
  color: #fff;
  font-size: 0.78rem;
  min-height: 44px;
  padding: 0 12px;
  flex-shrink: 0;
}

.habit-card-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
}

.habit-streak {
  font-weight: 600;
  margin-right: auto;
  min-width: 24px;
}

/* ---- Buttons ---- */

button {
  font: inherit;
  border: none;
  cursor: pointer;
  min-height: 44px;
  min-width: 44px;
  border-radius: 10px;
  padding: 0 14px;
}

.btn-primary {
  background: var(--primary);
  color: var(--primary-contrast);
  font-weight: 600;
}

.btn-secondary {
  background: transparent;
  color: var(--primary);
  border: 1px solid var(--primary);
}

.btn-danger {
  background: transparent;
  color: var(--danger);
  border: 1px solid var(--danger);
}

.btn-done {
  background: var(--border);
  color: var(--text-muted);
  font-size: 0.85rem;
  flex-grow: 1;
}

.btn-icon {
  background: transparent;
  color: var(--text-muted);
  padding: 0;
  font-size: 1.1rem;
}

.hidden { display: none !important; }

/* ---- Progress overview: weekly grid (feature 3). The synced trend line
   that used to sit below this grid (feature 5) was dropped on user
   request — see docs/PRODUCT.md and history-ui.js's chart instead. ---- */

.progress-overview {
  padding: 8px 16px 4px;
}

.week-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  margin-bottom: 10px;
}

.week-nav-group {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
}

.week-nav button {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  padding: 0;
}

.week-label {
  font-size: 0.85rem;
  color: var(--text-muted);
  padding: 0 10px;
  min-width: auto;
  white-space: nowrap;
}

/* The real <input type="date"> stays in the DOM (not display:none) so
   showPicker()/focus() reliably opens the native OS date picker on tap —
   just shrunk to 1px and made invisible. Triggered only via #week-label. */
.date-jump-input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  border: 0;
  opacity: 0;
  pointer-events: none;
}

.progress-grid {
  display: grid;
  grid-template-columns: 88px repeat(7, minmax(0, 1fr));
  gap: 4px;
  position: relative;
}

.today-highlight {
  background: var(--cell-today-bg);
  border-radius: 10px;
  margin: -6px;
  pointer-events: none;
}

.day-header {
  text-align: center;
  position: relative;
}

.day-header .day-label {
  font-size: 0.62rem;
  color: var(--text-muted);
  margin-top: 2px;
}

.day-header.is-today .day-label {
  color: var(--primary);
  font-weight: 600;
}

.day-toggle-btn {
  background: transparent;
  min-width: 0;
  min-height: 44px;
  width: 100%;
  padding: 8px 4px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.day-toggle {
  width: 26px;
  height: 15px;
  border-radius: 8px;
  background: var(--border);
  position: relative;
  transition: background 0.15s ease;
  flex-shrink: 0;
}

.day-toggle::after {
  content: '';
  position: absolute;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--surface);
  top: 2px;
  left: 2px;
  transition: left 0.15s ease;
}

.day-toggle.is-active {
  background: var(--primary);
}

.day-toggle.is-active::after {
  left: 13px;
}

.day-badge {
  margin-top: 2px;
  font-size: 0.68rem;
  font-weight: 600;
  color: #fff;
  border-radius: 6px;
  padding: 2px 0;
}

.day-badge.good { background: var(--day-good); }
.day-badge.mid { background: var(--day-mid); }
.day-badge.bad { background: var(--day-bad); }

.day-badge.off,
.day-badge.future {
  background: transparent;
  color: var(--text-muted);
  font-weight: 500;
}

.habit-row-label {
  font-size: 0.75rem;
  color: var(--text);
  white-space: normal;
  word-break: break-word;
  line-height: 1.25;
  padding: 4px 4px 4px 0;
  align-self: center;
}

.hcell {
  height: 44px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  padding: 0;
  min-width: 0;
  align-self: center;
}

.hcell.full {
  background: var(--cell-full-bg);
  border: 2px solid var(--cell-full-border);
  color: var(--cell-full-icon);
}

.hcell.two {
  background: transparent;
  border: 2px solid var(--cell-two-border);
  color: var(--cell-two-border);
}

.hcell.missed {
  background: var(--cell-missed-bg);
  border: none;
}

.hcell.future {
  background: var(--cell-future-bg);
  border: none;
}

.hcell.off {
  background: repeating-linear-gradient(45deg, var(--border) 0px, var(--border) 2px, var(--cell-future-bg) 2px, var(--cell-future-bg) 6px);
  border: none;
}

/* Per-habit weekday schedule (v9, H5 — feature 2 extension). Deliberately
   NOT the striped pattern used for .hcell.off above: that pattern means
   "globally off today" (feature 3b); this is a permanent, per-habit
   pattern, so it reuses the dashed-border idiom already used elsewhere in
   the app for "by design, not tracked" (e.g. .habit-env-toggle). */
.hcell.scheduled-off {
  background: var(--cell-future-bg);
  border: 1px dashed var(--border);
}

/* "Never miss twice" (Ch.16) surfaced on the grid itself, not just the
   habit card below — with several habits, a warning on one card is easy
   to miss while scanning; the grid stays compact and always in view.
   Only ever applied to TODAY's cell for a habit whose warning is
   currently active (see Habits.getWarning() / progress-ui.js), reusing
   the same --warning-bg/--warning-text tokens as .habit-warning so it
   reads as the same signal in both places. Declared after .hcell.missed
   so it wins on the (otherwise equal-specificity) 'hcell missed warning'
   cell — a warning cell is always also a missed cell. */
.hcell.warning {
  background: var(--warning-bg);
  border: 2px solid var(--warning-text);
  color: var(--warning-text);
}

.progress-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  font-size: 0.68rem;
  color: var(--text-muted);
  margin: 10px 0 4px;
}

.progress-legend .swatch {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 3px;
  margin-right: 4px;
  vertical-align: -1px;
}

.swatch-full { background: var(--cell-full-bg); border: 2px solid var(--cell-full-border); }
.swatch-two { border: 2px solid var(--cell-two-border); }
.swatch-missed { background: var(--cell-missed-bg); }
.swatch-future { background: var(--cell-future-bg); }
.swatch-off { background: repeating-linear-gradient(45deg, var(--border) 0px, var(--border) 2px, var(--cell-future-bg) 2px, var(--cell-future-bg) 6px); }
.swatch-scheduled-off { background: var(--cell-future-bg); border: 1px dashed var(--border); }
.swatch-warning { background: var(--warning-bg); border: 2px solid var(--warning-text); }

.trend-empty {
  font-size: 0.8rem;
  color: var(--text-muted);
  padding: 12px 0;
  text-align: center;
}

/* ---- FAB: primary action, bottom-right, one-handed thumb reach ---- */

.fab {
  position: fixed;
  /* Aligns with the .app-shell's right edge on wide (desktop) viewports;
     falls back to a plain 20px inset once the viewport is narrower than
     the shell's max-width, i.e. on an actual phone. */
  right: max(20px, calc((100vw - 480px) / 2 + 20px));
  bottom: max(20px, env(safe-area-inset-bottom));
  width: 56px;
  height: 56px;
  min-width: 56px;
  border-radius: 50%;
  background: var(--primary);
  color: var(--primary-contrast);
  font-size: 1.8rem;
  line-height: 1;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ---- Form overlay ---- */

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: flex-end;
  z-index: 10;
}

@media (min-width: 560px) {
  .overlay { align-items: center; justify-content: center; }
}

.habit-form {
  background: var(--surface);
  width: 100%;
  max-width: 480px;
  max-height: 92vh;
  overflow-y: auto;
  border-radius: var(--radius) var(--radius) 0 0;
  padding: 20px 16px calc(20px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 6px;
}

@media (min-width: 560px) {
  .habit-form { border-radius: var(--radius); }
}

.habit-form h2 {
  margin: 0 0 8px;
}

.habit-form label {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-top: 10px;
}

.habit-form input,
.habit-form textarea {
  font: inherit;
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
}

.habit-form textarea {
  resize: vertical;
  font-family: inherit;
}

.fieldset-inline {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 12px 12px;
  margin-top: 12px;
  display: flex;
  flex-direction: column;
}

.fieldset-inline legend {
  font-size: 0.8rem;
  color: var(--text-muted);
  padding: 0 4px;
}

.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 16px;
  flex-wrap: wrap;
}

/* ---- Identity chip picker in the habit form (feature 11, H2) ---- */

.form-label-standalone {
  display: block;
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-top: 10px;
}

.identity-chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
}

.identity-chip {
  min-height: 44px;
  padding: 0 14px;
  border-radius: 999px;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 0.88rem;
}

.identity-chip.is-selected {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--primary-contrast);
  font-weight: 600;
}

.identity-chip-add {
  min-width: 44px;
  padding: 0 14px;
  font-weight: 600;
  color: var(--primary);
  border-style: dashed;
}

.field-error {
  margin: 6px 0 0;
  font-size: 0.8rem;
  color: var(--danger);
}

/* ---- Weekday chip picker in the habit form (v9, H5 — feature 2
   extension). Same chip idiom as the identity picker above, but a fixed
   set of 7 multi-select day chips rather than a dynamic single-select
   list. ---- */

.weekday-chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 4px;
}

.weekday-chip {
  min-width: 44px;
  min-height: 44px;
  padding: 0 10px;
  border-radius: 999px;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 0.85rem;
  flex: 1 0 auto;
}

.weekday-chip.is-selected {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--primary-contrast);
  font-weight: 600;
}

/* ---- Identity contribution history (feature 5 extension, v1j, H1+H2) ---- */

.history-stats {
  margin: 0 0 10px;
  font-size: 0.82rem;
  color: var(--text-muted);
}

.identity-history-legend {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 10px;
}

.identity-history-group-header {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.85rem;
  font-weight: 600;
}

.identity-swatch {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 3px;
  flex-shrink: 0;
}

.identity-swatch-sm {
  width: 9px;
  height: 9px;
}

.identity-history-habits {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin: 4px 0 0 18px;
}

.identity-history-habit {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 0.78rem;
  color: var(--text-muted);
}

/* ---- Stemmen per periode: staafdiagram (feature 5-uitbreiding #2, H1+H2) ---- */
/* Reuses .trend-empty/.identity-swatch/.identity-history-habit chip look
   from the area chart above — only the pieces genuinely new to this
   section are defined here. */

.history-period-divider {
  margin-top: 16px;
  border-top: 1px solid var(--border);
  padding-top: 14px;
}

.history-period-heading {
  margin: 0 0 8px;
  font-size: 0.95rem;
}

.granularity-toggle {
  display: flex;
  gap: 6px;
  margin-bottom: 10px;
}

.granularity-btn {
  flex: 1;
  min-height: 44px;
  border-radius: 999px;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 0.85rem;
}

.granularity-btn.is-selected {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--primary-contrast);
  font-weight: 600;
}

.history-period-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}

.history-period-nav button {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  padding: 0;
  flex-shrink: 0;
}

.history-period-nav button:disabled {
  opacity: 0.35;
}

.history-period-label {
  font-size: 0.85rem;
  color: var(--text-muted);
  text-align: center;
  flex: 1;
}

.identity-period-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin-top: 8px;
}

/* ---- Identities overlay (feature 11, H2) ---- */
/* Add-row moved above the list (was below) + the list made its own
   scrollable region, on user request: the intro text, add-row and
   Sluiten-button now stay fixed in view, only the identities themselves
   scroll underneath. .scorecard-panel's own overflow-y:auto is disabled
   HERE ONLY (scoped to this overlay) so the panel stops being the scroll
   container; .identities-list becomes a flex child that grows to fill
   the remaining space up to the panel's existing 92vh cap and scrolls
   internally once it doesn't fit — a plain flex+min-height:0 pattern, no
   JS needed. Other .scorecard-panel-based overlays (history/scorecard/
   reflections/backup) are untouched. */

#identities-overlay .scorecard-panel {
  overflow-y: hidden;
}

.identities-list {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1 1 auto;
  min-height: 60px;
  overflow-y: auto;
}

.identity-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg);
}

.identity-item.is-archived {
  opacity: 0.65;
}

.identity-label {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 600;
}

.identity-count {
  margin: 2px 0 0;
  font-size: 0.78rem;
  color: var(--text-muted);
}

.identity-item-actions {
  display: flex;
  gap: 2px;
  flex-shrink: 0;
}

.identity-add-row {
  display: flex;
  gap: 8px;
  margin-bottom: 14px;
}

.identity-add-row input {
  flex: 1;
  font: inherit;
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
}

/* ---- Habits Scorecard overlay (feature 6) ---- */

.scorecard-panel {
  background: var(--surface);
  width: 100%;
  max-width: 480px;
  max-height: 92vh;
  overflow-y: auto;
  border-radius: var(--radius) var(--radius) 0 0;
  padding: 20px 16px calc(20px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
}

@media (min-width: 560px) {
  .scorecard-panel { border-radius: var(--radius); }
}

.scorecard-panel h2 {
  margin: 0 0 6px;
}

.scorecard-intro {
  margin: 0 0 14px;
  font-size: 0.82rem;
  color: var(--text-muted);
  line-height: 1.4;
}

.scorecard-add-form {
  display: flex;
  gap: 8px;
  margin-bottom: 14px;
}

.scorecard-add-form input {
  flex: 1;
  font: inherit;
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
}

.scorecard-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.scorecard-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg);
}

.scorecard-text {
  flex: 1 1 100%;
  font-size: 0.9rem;
  word-break: break-word;
}

.scorecard-ratings {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
  margin-right: auto;
}

/* Full 44x44 touch target, matching the rest of the app's tap-target rule. */
.rating-btn {
  width: 44px;
  min-width: 44px;
  height: 44px;
  min-height: 44px;
  padding: 0;
  border-radius: 8px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-weight: 600;
}

.rating-plus.is-active { background: var(--day-good); border-color: var(--day-good); color: #fff; }
.rating-equals.is-active { background: var(--text-muted); border-color: var(--text-muted); color: var(--surface); }
.rating-minus.is-active { background: var(--danger); border-color: var(--danger); color: #fff; }

.scorecard-delete {
  flex-shrink: 0;
}

/* ---- Scorecard → bad habit bridge (feature 15, v13, H4 → inversie 4
   wetten) ---- */
/* Own full-width line (like .scorecard-text above), not squeezed onto the
   ratings row — the label can be as long as a habit name. Danger-tinted
   dashed border while actionable (not yet linked), same idiom as
   .habit-env-toggle's "open" state; once linked it calms down to the
   neutral border/text-muted pairing — there's still an action (open to
   edit), but it's no longer a call to action. */
.scorecard-badhabit-link {
  flex: 1 1 100%;
  text-align: left;
  font-size: 0.82rem;
  background: transparent;
  color: var(--danger);
  border: 1px dashed var(--danger);
}

.scorecard-badhabit-link.is-linked {
  color: var(--text-muted);
  border: 1px solid var(--border);
}

/* ---- Habit contracts overlay (feature 7) ---- */

.contract-panel {
  background: var(--surface);
  width: 100%;
  max-width: 480px;
  max-height: 92vh;
  overflow-y: auto;
  border-radius: var(--radius) var(--radius) 0 0;
  padding: 20px 16px calc(20px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
}

@media (min-width: 560px) {
  .contract-panel { border-radius: var(--radius); }
}

.contract-panel h2 {
  margin: 0 0 6px;
}

.contracts-list {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.contract-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 14px;
}

.contract-title {
  margin: 0 0 4px;
  font-size: 1.05rem;
}

.contract-commitment {
  margin: 0 0 6px;
  font-size: 0.88rem;
}

.contract-meta-line {
  margin: 2px 0;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.contract-meta-line.contract-signed.is-signed {
  color: var(--day-good);
  font-weight: 600;
}

.contract-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
}

.contract-actions .contract-edit-btn {
  margin-left: auto;
}

/* ---- Habit checkboxes in the contract form ---- */

.habit-checkbox-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.habit-checkbox-item {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 2px 0;
  font-size: 0.9rem;
}

.habit-checkbox-item input[type="checkbox"] {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.habit-checkbox-empty {
  font-size: 0.85rem;
  color: var(--text-muted);
  padding: 4px 0;
}

/* ---- Goldilocks levels overlay (feature 10, H19) ---- */

.habit-levels-btn {
  width: 100%;
  margin-top: 10px;
}

.levels-rows {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 4px 0 12px;
}

.level-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}

.level-current-radio {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.level-desc-input {
  flex: 1;
  font: inherit;
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
}

.levels-add-btn {
  width: 100%;
}

/* ---- Bad habit breaking overlay (feature 13, inversion of the 4 Laws) ---- */
/* .badhabit-card reuses .contract-card; .badhabit-cue-toggle reuses
   .habit-env-toggle (1.5, same registration+confirm idiom as feature 9);
   .badhabit-benefits/.badhabit-friction-list reuse .habit-benefits (2.4/
   4.2 and 3.6); .badhabit-commitment/.badhabit-contract reuse
   .contract-meta-line; .badhabit-warning reuses .habit-warning. Only the
   pieces below are genuinely new. */

.badhabit-friction-list li::before {
  content: '🧱';
}

.badhabit-tracking {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

.badhabit-days {
  font-weight: 600;
  margin-right: auto;
  font-size: 0.9rem;
}

.badhabit-relapse-btn {
  font-size: 0.82rem;
}

.badhabit-relapse-btn:disabled {
  opacity: 0.6;
  cursor: default;
}

/* ---- Tracking-toggle checkbox in the bad-habit form ---- */

.badhabit-tracking-label {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.badhabit-tracking-label input[type="checkbox"] {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

/* ---- Reflection & Review overlay (feature 16, H20 + Conclusion) ---- */
/* .reflection-card reuses .contract-card; .reflection-date/.reflection-stats
   reuse .contract-meta-line. Only the pieces below are genuinely new. */

.reflection-type-badge {
  margin: 0 0 4px;
  font-size: 0.95rem;
  font-weight: 600;
}

.reflection-qa {
  margin: 8px 0 0;
}

.reflection-qa dt {
  font-size: 0.78rem;
  color: var(--text-muted);
  margin-top: 8px;
}

.reflection-qa dt:first-child {
  margin-top: 0;
}

.reflection-qa dd {
  margin: 2px 0 0;
  font-size: 0.88rem;
  white-space: pre-wrap;
}

/* Read-only computed context shown at the top of the new-reflection form
   (H20 — Clear tallies his habits before answering the reflection
   questions themselves). Boxed like .fieldset-inline so it visually reads
   as "given", not as an editable field. */
.reflection-stats-box {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
  margin: 4px 0 10px;
  font-size: 0.82rem;
  color: var(--text-muted);
}

/* Bugfix: the annual/integrity field groups are plain wrapper <div>s
   (needed so ui.js can toggle one set hidden depending on `type`), but
   .habit-form's label/textarea layout rules only apply to DIRECT
   children of its flex container (flex blockifies inline-level children
   like <label>/<textarea> to make them stack full-width). Nested one
   level deeper inside a plain block <div>, those same elements keep
   their default inline/inline-block display and wrap side-by-side like
   text instead of stacking — the layout bug reported by the user.
   display:contents removes the wrapper from box generation so its
   children become direct flex items of .habit-form again, with no
   visual difference other than fixing the stacking. `.hidden`'s
   `display: none !important` still wins over this (non-important) rule
   whenever ui.js toggles a group hidden, so the show/hide logic is
   unaffected. */
#reflection-annual-fields,
#reflection-integrity-fields {
  display: contents;
}

/* ---- Data & privacy overlay (backlog items 2-5, datahygiëne) ---- */
/* Reuses .scorecard-panel/.scorecard-intro/.form-actions/.btn-danger; the
   panel isn't a <form> (several independent actions, not one submit), so
   label/input/select styling is scoped to this overlay specifically
   rather than reusing .habit-form's rules. Only the pieces genuinely new
   to this overlay are defined here. */

#backup-overlay label {
  display: block;
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-top: 10px;
}

#backup-overlay input[type="text"],
#backup-overlay input[type="password"],
#backup-overlay select {
  font: inherit;
  width: 100%;
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  margin-top: 4px;
}

.backup-section-heading {
  margin: 18px 0 6px;
  font-size: 0.95rem;
}

.backup-status {
  margin: 0 0 10px;
  font-size: 0.82rem;
  color: var(--text-muted);
}

.backup-inline-row {
  display: flex;
  gap: 8px;
  align-items: flex-start;
}

.backup-inline-row input {
  flex: 1;
}

.backup-inline-row button {
  margin-top: 4px;
}

.backup-file-label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.archive-list {
  margin-bottom: 10px;
}

.archive-group-heading {
  margin: 10px 0 4px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-muted);
}

.archive-empty {
  margin: 0 0 6px;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.archive-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg);
  margin-bottom: 6px;
  flex-wrap: wrap;
}

.archive-item-label {
  flex: 1;
  font-size: 0.88rem;
  font-weight: 600;
}

.archive-item-note {
  font-size: 0.75rem;
  color: var(--text-muted);
  flex-shrink: 0;
}

.archive-item-delete {
  font-size: 0.78rem;
  flex-shrink: 0;
}

.archive-item-delete:disabled {
  opacity: 0.35;
  cursor: default;
}
