/* calendar.css — Tokens used summary
 *
 * Layout and visual design for the interactive calendar. Self-contained,
 * no external assets, no inline styles, no JS-driven styling outside the
 * documented data-* state attributes consumed by `.day[data-state=...]`
 * and `.day[data-level=...]`.
 *
 * Themes:
 *   :root                    — light defaults; applied when the user
 *                              agent does NOT request dark.
 *   :root[data-theme=dark]   — explicit dark, applied when JS reads
 *                              matchMedia('(prefers-color-scheme: dark)').
 *   @media (prefers-color-scheme: dark) — automatic dark, only used
 *                              when no manual data-theme override is set.
 */

:root {
  color-scheme: light;
  --bg: #ffffff;
  --fg: #1a1a1a;
  --fg-muted: #555a60;
  --fg-faint: #6b727a;
  --border: #d8dde2;
  --border-strong: #b7bdc4;
  --link: #0a5d8a;
  --link-visited: #5a3a8c;
  --hover: #eef3f7;
  --focus-ring: #0a5d8a;

  /* Measured levels. Low-to-high intensity inside the same hue family
     so users feel scale, not hue changes. */
  --day-measured-fg: rgba(0, 0, 0, 0.55);
  --day-level-0: #e6efe7;
  --day-level-1: #b9d6bf;
  --day-level-2: #79b48a;
  --day-level-3: #358557;
  --day-level-4: #185a31;

  /* Non-measured states. */
  --day-unknown-bg: repeating-linear-gradient(
    45deg,
    #eef0f2,
    #eef0f2 4px,
    #dfe3e6 4px,
    #dfe3e6 8px
  );
  --day-unknown-border: #b8bec4;
  --day-pending-bg: rgba(216, 221, 226, 0.35);
  --day-pending-border: rgba(184, 190, 196, 0.55);

  --tooltip-bg: #1a1a1a;
  --tooltip-fg: #f5f5f5;
  --dialog-bg: #ffffff;
  --dialog-backdrop: rgba(10, 15, 20, 0.45);

  --gap: 6px;
  --radius: 4px;
  --max-width: 1200px;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0f141a;
  --fg: #e6ebef;
  --fg-muted: #a7b1ba;
  --fg-faint: #77808a;
  --border: #243038;
  --border-strong: #3a4754;
  --link: #6cb6e8;
  --link-visited: #b48de0;
  --hover: #18222c;
  --focus-ring: #6cb6e8;

  --day-measured-fg: rgba(255, 255, 255, 0.85);
  --day-level-0: #1c2a24;
  --day-level-1: #2a4a37;
  --day-level-2: #3d7856;
  --day-level-3: #4ea57a;
  --day-level-4: #82d4a8;

  --day-unknown-bg: repeating-linear-gradient(
    45deg,
    #18222c,
    #18222c 4px,
    #202a35 4px,
    #202a35 8px
  );
  --day-unknown-border: #2c3942;
  --day-pending-bg: rgba(36, 48, 56, 0.4);
  --day-pending-border: rgba(58, 71, 84, 0.55);

  --tooltip-bg: #f5f5f5;
  --tooltip-fg: #0f141a;
  --dialog-bg: #15202a;
  --dialog-backdrop: rgba(0, 0, 0, 0.6);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;
    --bg: #0f141a;
    --fg: #e6ebef;
    --fg-muted: #a7b1ba;
    --fg-faint: #77808a;
    --border: #243038;
    --border-strong: #3a4754;
    --link: #6cb6e8;
    --link-visited: #b48de0;
    --hover: #18222c;
    --focus-ring: #6cb6e8;

    --day-measured-fg: rgba(255, 255, 255, 0.85);
    --day-level-0: #1c2a24;
    --day-level-1: #2a4a37;
    --day-level-2: #3d7856;
    --day-level-3: #4ea57a;
    --day-level-4: #82d4a8;

    --day-unknown-bg: repeating-linear-gradient(
      45deg,
      #18222c,
      #18222c 4px,
      #202a35 4px,
      #202a35 8px
    );
    --day-unknown-border: #2c3942;
    --day-pending-bg: rgba(36, 48, 56, 0.4);
    --day-pending-border: rgba(58, 71, 84, 0.55);

    --tooltip-bg: #f5f5f5;
    --tooltip-fg: #0f141a;
    --dialog-bg: #15202a;
    --dialog-backdrop: rgba(0, 0, 0, 0.6);
  }
}

* {
  box-sizing: border-box;
}

html {
  background: var(--bg);
  color: var(--fg);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue",
    Arial, "Liberation Sans", sans-serif;
  font-size: 16px;
  line-height: 1.45;
}

body {
  margin: 0 auto;
  padding: 1.5rem 1rem 3rem;
  max-width: var(--max-width);
  background: var(--bg);
  color: var(--fg);
}

.skip-link {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.skip-link:focus {
  left: 1rem;
  top: 1rem;
  width: auto;
  height: auto;
  padding: 0.5rem 0.75rem;
  background: var(--bg);
  color: var(--fg);
  border: 2px solid var(--focus-ring);
  z-index: 100;
}

.page-header {
  margin-bottom: 1.5rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--border);
}

.page-header h1 {
  font-size: 1.5rem;
  font-weight: 600;
  margin: 0 0 0.25rem;
  line-height: 1.2;
}

.page-tagline {
  margin: 0;
  color: var(--fg-muted);
  font-size: 0.95rem;
}

.profile-link {
  color: var(--link);
  text-decoration: none;
}

.profile-link:visited {
  color: var(--link-visited);
}

.profile-link:hover,
.profile-link:focus-visible {
  text-decoration: underline;
}

a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.page-main {
  display: flex;
  flex-direction: column;
  gap: 2.5rem;
}

.summary h2 {
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0 0 0.25rem;
}

.summary-subtitle {
  margin: 0 0 1rem;
  color: var(--fg-muted);
  font-size: 0.95rem;
}

.summary-figure {
  margin: 0 0 1rem;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.25rem 1.5rem;
  max-width: 28rem;
}

.summary-figure-row {
  display: contents;
}

.summary-figure dt {
  color: var(--fg-muted);
  font-size: 0.9rem;
  align-self: end;
}

.summary-figure dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
  font-size: 1.25rem;
  font-weight: 600;
}

.summary-note {
  margin: 0;
  max-width: 38rem;
  color: var(--fg-muted);
  font-size: 0.9rem;
}

/* ------------------------------------------------------------------
   Calendar
   ------------------------------------------------------------------ */

.calendar h2 {
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0 0 0.25rem;
}

.calendar-provenance {
  margin: 0 0 0.5rem;
  color: var(--fg-muted);
  font-size: 0.85rem;
}

.calendar-status {
  margin: 0 0 1rem;
  color: var(--fg-muted);
  font-size: 0.9rem;
}

.calendar-status[data-state="error"] {
  color: #b53a3a;
}

:root[data-theme="dark"] .calendar-status[data-state="error"] {
  color: #e88080;
}

.calendar-error {
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 1rem;
  margin-bottom: 1rem;
  background: var(--hover);
}

.calendar-error p {
  margin: 0;
}

.calendar-noscript {
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  padding: 1rem;
  margin-bottom: 1rem;
  background: var(--hover);
  color: var(--fg-muted);
  font-size: 0.9rem;
}

.calendar-grid {
  display: grid;
  gap: 1.5rem;
}

.calendar-month {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.75rem;
}

.calendar-month h3 {
  margin: 0 0 0.5rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--fg-muted);
}

.calendar-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: var(--gap);
  margin-bottom: var(--gap);
  font-size: 0.7rem;
  color: var(--fg-faint);
  text-align: center;
}

.calendar-weekdays span {
  padding: 0.1rem 0;
}

.calendar-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: var(--gap);
}

.calendar-days .day-spacer {
  /* Inactive leading or trailing cells. */
  visibility: hidden;
}

/* Day cell. A <button> so it is naturally focusable, clickable, and
   keyboard-activatable. Visual states come from data-* attributes. The
   JS sets data-date, data-state, and data-level. */

button.day {
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  color: inherit;
  background: var(--day-level-0);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  aspect-ratio: 1 / 1;
  width: 100%;
  padding: 0;
  margin: 0;
  cursor: pointer;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

button.day[disabled] {
  cursor: default;
}

button.day[data-state="unknown"] {
  background: var(--day-unknown-bg);
  color: var(--fg-faint);
  border-color: var(--day-unknown-border);
}

button.day[data-state="pending"] {
  background: var(--day-pending-bg);
  color: var(--fg-faint);
  border-color: var(--day-pending-border);
}

button.day[data-state="measured"][data-level="0"] { background: var(--day-level-0); color: var(--day-measured-fg); }
button.day[data-state="measured"][data-level="1"] { background: var(--day-level-1); color: var(--day-measured-fg); }
button.day[data-state="measured"][data-level="2"] { background: var(--day-level-2); color: var(--day-measured-fg); }
button.day[data-state="measured"][data-level="3"] { background: var(--day-level-3); color: var(--day-measured-fg); }
button.day[data-state="measured"][data-level="4"] { background: var(--day-level-4); color: var(--day-measured-fg); }

button.day:hover[data-state="measured"] {
  box-shadow: 0 0 0 1px var(--border-strong);
  z-index: 1;
}

button.day:hover[data-state="unknown"],
button.day:hover[data-state="pending"] {
  border-color: var(--border-strong);
  z-index: 1;
}

/* Legend swatches reuse the day styles. They are not interactive. */

.calendar-legend {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  font-size: 0.8rem;
  color: var(--fg-muted);
}

.calendar-legend li {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.legend-swatch {
  display: inline-block;
  width: 0.9rem;
  height: 0.9rem;
  border: 1px solid var(--border);
  border-radius: 2px;
}

.legend-swatch[data-state="measured"][data-level="0"] { background: var(--day-level-0); }
.legend-swatch[data-state="measured"][data-level="1"] { background: var(--day-level-1); }
.legend-swatch[data-state="measured"][data-level="2"] { background: var(--day-level-2); }
.legend-swatch[data-state="measured"][data-level="3"] { background: var(--day-level-3); }
.legend-swatch[data-state="measured"][data-level="4"] { background: var(--day-level-4); }
.legend-swatch[data-state="unknown"] { background: var(--day-unknown-bg); border-color: var(--day-unknown-border); }
.legend-swatch[data-state="pending"] { background: var(--day-pending-bg); border-color: var(--day-pending-border); }

/* ------------------------------------------------------------------
   Tooltip and dialog
   ------------------------------------------------------------------ */

.day-tooltip {
  position: fixed;
  z-index: 50;
  background: var(--tooltip-bg);
  color: var(--tooltip-fg);
  padding: 0.5rem 0.7rem;
  border-radius: var(--radius);
  font-size: 0.78rem;
  line-height: 1.3;
  max-width: 18rem;
  pointer-events: none;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
}

.day-tooltip[hidden] {
  display: none;
}

.day-tooltip-date {
  font-weight: 600;
  margin: 0 0 0.15rem;
  font-variant-numeric: tabular-nums;
}

.day-tooltip-value {
  margin: 0;
  font-variant-numeric: tabular-nums;
}

.day-tooltip-value[data-state="unknown"]::before {
  content: "no measurement";
}

.day-tooltip-value[data-state="pending"]::before {
  content: "not yet reported";
}

.day-tooltip-value[data-state="pending"] {
  color: var(--tooltip-fg);
  opacity: 0.7;
}

.day-tooltip-note {
  margin: 0.3rem 0 0;
  opacity: 0.7;
  font-size: 0.7rem;
}

/* Native <dialog>. We restyle it; the JS just uses showModal()/close(). */

.day-dialog {
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 1.25rem 1.5rem;
  background: var(--dialog-bg);
  color: var(--fg);
  max-width: 28rem;
  width: calc(100vw - 2rem);
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.25);
}

.day-dialog::backdrop {
  background: var(--dialog-backdrop);
}

.day-dialog-form {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.day-dialog-title {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 600;
}

.day-dialog-date {
  margin: 0;
  color: var(--fg-muted);
  font-variant-numeric: tabular-nums;
  font-size: 0.9rem;
}

.day-dialog-meta {
  margin: 0;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.25rem 1rem;
}

.day-dialog-meta > div {
  display: contents;
}

.day-dialog-meta dt {
  color: var(--fg-muted);
  font-size: 0.85rem;
  align-self: end;
}

.day-dialog-meta dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: 0.95rem;
}

.day-dialog-meta dd[data-state="pending"] {
  color: var(--fg-faint);
  font-weight: 400;
}

.day-dialog-meta dd[data-state="unknown"] {
  color: var(--fg-muted);
  font-weight: 400;
}

.day-dialog-note {
  margin: 0;
  font-size: 0.78rem;
  color: var(--fg-muted);
}

.day-dialog-close {
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  align-self: flex-end;
  background: var(--fg);
  color: var(--bg);
  border: 1px solid var(--fg);
  border-radius: var(--radius);
  padding: 0.45rem 1rem;
  cursor: pointer;
  font-weight: 600;
}

/* ------------------------------------------------------------------
   Mobile: split the year into two half-year rows.
   ------------------------------------------------------------------ */

@media (max-width: 720px) {
  body {
    padding: 1rem 0.75rem 2.5rem;
  }

  .calendar-grid {
    /* No horizontal scroll; the grid wraps via auto-fit. On narrow
       screens each month stays wide enough to read. */
    grid-template-columns: 1fr;
    gap: 1rem;
  }

  .summary-figure {
    grid-template-columns: 1fr;
  }

  .summary-figure-row {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.15rem;
    border-bottom: 1px solid var(--border);
    padding: 0.5rem 0;
  }

  .summary-figure-row:last-child {
    border-bottom: 0;
  }

  .summary-figure dt {
    font-size: 0.85rem;
  }

  button.day {
    font-size: 0.65rem;
  }

  .day-tooltip {
    max-width: 14rem;
  }
}

@media (min-width: 721px) and (max-width: 1024px) {
  .calendar-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1025px) {
  .calendar-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* Reduced-motion: nothing animates today, but declare this for the
   future so transitions stay opt-in. */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition: none;
    animation: none;
  }
}

/* The buttons that are not currently in the roving tab order are kept
   focusable for screen readers but skipped by Tab. JS manages this with
   the [data-roving-tab] attribute. */

button.day[data-roving-tab="false"] {
  /* Nothing visually changes; this exists as a stable hook so styles
     and JS stay decoupled. */
}

.page-footer {
  margin-top: 3rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  color: var(--fg-muted);
  font-size: 0.85rem;
  text-align: center;
}

/* Annual heatmap: one element per date, two half-year rows on mobile. */
:root {
  --bg: #f6f6f4;
  --fg: #0c1014;
  --fg-muted: #3d4750;
  --fg-faint: #5e6571;
  --link: #085246;
  --link-visited: #085246;
  --focus-ring: #085246;
  --day-level-0: #f1f3f1;
  --day-level-1: #d1eee2;
  --day-level-2: #8bceae;
  --day-level-3: #359a74;
  --day-level-4: #085246;
  --max-width: 920px;
}
:root[data-theme="dark"] {
  --bg: #0e1014;
  --fg: #f4f6f8;
  --fg-muted: #b6bcc6;
  --fg-faint: #8a909a;
  --link: #35d9a0;
  --link-visited: #35d9a0;
  --focus-ring: #35d9a0;
  --day-level-0: #1b1f26;
  --day-level-1: #164b3d;
  --day-level-2: #14694f;
  --day-level-3: #13936c;
  --day-level-4: #35d9a0;
}
body { padding: 40px 24px; }
.page-header { border: 0; margin-bottom: 32px; padding: 0; }
.page-main { gap: 28px; }
.summary h1 { font-size: clamp(24px, 4vw, 32px); margin: 0 0 6px; line-height: 1.15; letter-spacing: -0.6px; }
.summary-figure { display: block; margin: 18px 0 12px; max-width: none; }
.summary-figure-row { display: flex; flex-direction: column; gap: 4px; border: 0; padding: 0; }
.summary-figure dt { align-self: flex-start; }
.summary-figure dd { font-size: clamp(22px, 4vw, 32px); font-weight: 650; letter-spacing: -0.5px; overflow-wrap: anywhere; }
.calendar h2 { font-size: 16px; }
.calendar-provenance { line-height: 1.6; }
.calendar-status { font-size: 12px; margin-bottom: 26px; }
.calendar-grid { display: grid; padding-left: 22px; grid-template-columns: minmax(0, calc((100% + 3px) * 26 / var(--total-columns) - 3px)) minmax(0, 1fr); gap: 3px; }
.calendar-grid[hidden] { display: none; }
.calendar-block { min-width: 0; position: relative; padding-left: 0; }
.calendar-block + .calendar-block { padding-left: 0; }
.calendar-month-labels { display: grid; grid-template-columns: repeat(var(--columns), minmax(0, 1fr)); gap: 3px; height: 24px; font-size: 11px; color: var(--fg-faint); }
.calendar-month-labels span { white-space: nowrap; }
.calendar-week-grid { display: grid; grid-template-columns: repeat(var(--columns), minmax(0, 1fr)); grid-template-rows: repeat(7, auto); grid-auto-flow: column; gap: 3px; }
.calendar-row-labels { position: absolute; left: -22px; top: 24px; bottom: 0; width: 16px; display: grid; grid-template-rows: repeat(7, 1fr); gap: 3px; align-items: center; color: var(--fg-faint); font-size: 10px; }
.calendar-block + .calendar-block .calendar-row-labels { display: none; }
.calendar-week-grid .day-spacer { aspect-ratio: 1; }
.calendar-week-grid button.day { border-radius: 3px; min-width: 0; aspect-ratio: 1; }
.calendar-legend { margin: 24px 0 12px; font-size: 11px; }
.summary-note { font-size: 12px; line-height: 1.7; }
.day-tooltip { pointer-events: auto; max-width: min(280px, calc(100vw - 16px)); border-radius: 10px; padding: 12px 16px; }
.day-tooltip-value[data-state="unknown"]::before, .day-tooltip-value[data-state="pending"]::before { content: none; }
.day-dialog { border-radius: 16px; }
.day-dialog-meta { display: flex; flex-direction: column; gap: 12px; }
.day-dialog-meta > div { display: flex; flex-direction: column; gap: 3px; }
.day-dialog-meta dd { overflow-wrap: anywhere; }
#daily-value { font-size: 24px; letter-spacing: -0.4px; }
.day-dialog-close { min-height: 44px; border-radius: 8px; }
.page-footer { border: 0; margin-top: 28px; text-align: left; font-size: 12px; }
@media (max-width: 599px) {
  body { padding: 24px 16px; }
  .calendar-grid { grid-template-columns: minmax(0, 1fr); gap: 24px; padding-left: 0; }
  .calendar-block { padding-left: 22px; }
  .calendar-block + .calendar-block { padding-left: 22px; }
  .calendar-block + .calendar-block .calendar-row-labels { display: grid; }
  .calendar-month-labels, .calendar-week-grid { gap: 2px; }
  .calendar-week-grid button.day { border-radius: 2px; }
  .calendar-row-labels { gap: 2px; left: 0; }
  .day-dialog { padding: 20px; }
}
