/* Full-screen calendar, two layouts, two themes.
 *
 * Nothing scrolls except the calendar canvas and the drawers. The app is sized in dvh so
 * that a phone's collapsing address bar does not leave a strip of blank page below it. */

/* ---- theme tokens -------------------------------------------------------------------
 * Light is the default. Dark is declared twice on purpose: once for the system
 * preference, once for an explicit choice. CSS has no way to share a declaration block
 * between two selectors, and a preprocessor is not worth adding for one duplication. */
:root {
  color-scheme: light;
  --bg: #f4f5f7;
  --panel: #ffffff;
  --panel-2: #fbfbfc;
  --ink: #1a1c22;
  --muted: #6b7280;
  --line: #e3e5ea;
  --line-strong: #cdd1d9;
  --accent: #4C7EF3;
  --accent-ink: #ffffff;
  --today: #fff4d9;
  --today-ink: #7a5300;
  --danger: #c0392b;
  --unassigned: #8a90a0;
  --shadow: 0 10px 30px rgba(20, 22, 27, .16);
  --radius: 10px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #101216;
    --panel: #191c22;
    --panel-2: #1f232b;
    --ink: #e8eaf0;
    --muted: #9aa1ae;
    --line: #2a2f38;
    --line-strong: #3a414d;
    --accent: #6f9bff;
    --accent-ink: #0d1017;
    --today: #33290f;
    --today-ink: #ffd88a;
    --danger: #e26d5c;
    --unassigned: #79808f;
    --shadow: 0 10px 30px rgba(0, 0, 0, .5);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #101216;
  --panel: #191c22;
  --panel-2: #1f232b;
  --ink: #e8eaf0;
  --muted: #9aa1ae;
  --line: #2a2f38;
  --line-strong: #3a414d;
  --accent: #6f9bff;
  --accent-ink: #0d1017;
  --today: #33290f;
  --today-ink: #ffd88a;
  --danger: #e26d5c;
  --unassigned: #79808f;
  --shadow: 0 10px 30px rgba(0, 0, 0, .5);
}

/* ---- frame --------------------------------------------------------------------------- */
* { box-sizing: border-box; }

/* Every panel here sets `display` in a class and is toggled by the `hidden` attribute.
 * An author `display` rule outranks the browser's own [hidden] rule, so without this the
 * app, both curtains, the drawer and the day overlay all render at once. */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;                     /* only the canvas and drawers scroll */
}

body {
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.4 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
}

.app {
  display: grid;
  grid-template-rows: auto 1fr;
  height: 100dvh;
  padding-top: env(safe-area-inset-top);
}

/* A column so the month and week grids can take the remaining height. "Full screen"
 * has to mean the calendar fills the screen, not that it sits at the top of one. */
.canvas {
  overflow: auto;
  padding: 10px;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.muted { color: var(--muted); font-size: .82rem; }
.error { color: var(--danger); font-size: .85rem; }
.spacer { flex: 1; }

/* ---- controls ------------------------------------------------------------------------ */
button, .button {
  font: inherit;
  color: var(--ink);
  background: var(--panel);
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  padding: .4rem .75rem;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  white-space: nowrap;
}
button:hover, .button:hover { border-color: var(--accent); }
button:focus-visible, .button:focus-visible,
.day:focus-visible, .chip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
button.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
button.ghost, .button.ghost { background: transparent; border-color: var(--line); }
button.danger { color: var(--danger); border-color: var(--danger); background: transparent; }
button.icon { padding: .35rem .6rem; font-size: 1.05rem; line-height: 1; }
button[disabled] { opacity: .5; cursor: default; }

/* ---- top line ------------------------------------------------------------------------ */
.topbar {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .5rem .7rem;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}
.bar-nav { display: flex; align-items: center; gap: .35rem; min-width: 0; }
.bar-nav h1 {
  font-size: 1.02rem;
  margin: 0 0 0 .45rem;
  font-weight: 650;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bar-who { margin-left: auto; display: flex; align-items: center; gap: .5rem; }

.identity {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .88rem;
  color: var(--muted);
  max-width: 14ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dot { width: .7rem; height: .7rem; border-radius: 50%; background: var(--accent); flex: none; }

.zoombar { display: flex; border: 1px solid var(--line-strong); border-radius: 8px; overflow: hidden; }
.zoombar button {
  border: 0;
  border-radius: 0;
  background: transparent;
  padding: .38rem .7rem;
  font-size: .86rem;
}
.zoombar button + button { border-left: 1px solid var(--line); }
.zoombar button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.phone-zoom { display: none; }

/* ---- shared calendar pieces ----------------------------------------------------------- */
.weekhead {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  color: var(--muted);
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  padding: 0 0 .3rem;
}
.weekhead span { text-align: center; }

/* A column of week rows, not one flat grid of days: a spanning bar is positioned across
   the columns of its own week, which needs that week to be a grid in its own right. The
   1px gaps over a line-coloured background still draw every cell border. */
.grid {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.weekrow {
  position: relative;
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  background: var(--line);
  flex: 1;
  min-height: 5.5rem;
}

/* The bars float over the cells and take no space in them, so each cell reserves exactly
   the height they occupy. --lanes is set on the week row by the renderer. */
.day .lanespace { flex: none; height: calc(var(--lanes, 0) * 1.2rem); }

.spans {
  position: absolute;
  /* Clears the day number, which stays at the top of its cell. */
  inset: 1.45rem 0 auto 0;
  display: grid;
  grid-template-columns: repeat(var(--cols, 7), 1fr);
  grid-auto-rows: 1.2rem;
  gap: 1px;
  /* The layer must not eat clicks meant for the day cell underneath; only the bars do. */
  pointer-events: none;
  z-index: 2;
}

.bar {
  pointer-events: auto;
  align-self: start;
  height: 1.05rem;
  /* The line box is the bar's height, so the text sits centred whatever the button's
     own alignment does; relying on flex centring left the text half above the bar. */
  line-height: 1.05rem;
  margin: 0 .25rem;
  display: flex;
  align-items: center;
  border: 0;
  border-left: 3px solid var(--accent);
  border-radius: 3px;
  background: color-mix(in srgb, var(--accent) 22%, var(--panel));
  padding: 0 .3rem;
  font: inherit;
  font-size: .72rem;
  color: inherit;
  cursor: pointer;
  overflow: hidden;
}
.bar .what { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1.05rem; }
.bar.unassigned { --accent: var(--unassigned); }
/* Cut ends, for a run that began before this week or carries on past it. */
.bar.from-before { margin-left: 0; border-left: 0; border-top-left-radius: 0; border-bottom-left-radius: 0; }
.bar.into-after { margin-right: 0; border-top-right-radius: 0; border-bottom-right-radius: 0; }

.day {
  background: var(--panel);
  border: 0;
  border-radius: 0;
  padding: .3rem .35rem;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: .15rem;
  text-align: left;
  font: inherit;
  color: inherit;
  min-height: 5.5rem;
  overflow: hidden;
}
.day:hover { background: var(--panel-2); }
.day.outside { opacity: .42; }
.day.today { background: var(--today); }
.day .num { font-size: .78rem; color: var(--muted); flex: none; }
.day.today .num { color: var(--today-ink); font-weight: 700; }
.day .more { font-size: .7rem; color: var(--muted); }

.chip {
  display: flex;
  align-items: baseline;
  gap: .3rem;
  width: 100%;
  border: 0;
  border-left: 3px solid var(--accent);
  border-radius: 3px;
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  padding: .08rem .3rem;
  font: inherit;
  font-size: .76rem;
  color: inherit;
  text-align: left;
  overflow: hidden;
  flex: none;
}
.chip.unassigned { --accent: var(--unassigned); }
.chip:hover { background: color-mix(in srgb, var(--accent) 28%, transparent); }
.chip .when { color: var(--muted); font-variant-numeric: tabular-nums; flex: none; }
.chip .what { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- year ----------------------------------------------------------------------------- */
.year { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.mini {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: .5rem;
}
.mini h3 { margin: 0 0 .35rem; font-size: .82rem; font-weight: 650; }
.mini .mini-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; }
.mini .mini-head { color: var(--muted); font-size: .58rem; text-align: center; }
.mini .mini-day {
  aspect-ratio: 1;
  border: 0;
  background: transparent;
  border-radius: 4px;
  font: inherit;
  font-size: .68rem;
  color: var(--ink);
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  cursor: pointer;
}
.mini .mini-day.outside { color: var(--muted); opacity: .45; }
.mini .mini-day.today { background: var(--today); color: var(--today-ink); font-weight: 700; }
.mini .mini-day:hover { background: var(--panel-2); outline: 1px solid var(--accent); }
.mini .pips { display: flex; gap: 1px; height: 3px; }
.mini .pip { width: 3px; height: 3px; border-radius: 50%; background: var(--accent); }

/* ---- the wordmark ---------------------------------------------------------------------- */
/* 3Cal (Family Calendar, then briefly WeCAL, until 2026-09-20), in the same cut as the Travel
   Planner mark: the capitals carry three bands — blue, violet, amber, in that order — the
   way the 3sCompany.app numeral does. Here the numeral is the banded block; "Cal" is ink.

   Painted as a hard-stopped gradient clipped to the glyph rather than three stacked copies,
   so the letters stay real text: selectable, searchable and correct at any size. The stops
   are percentages of the line box, and the line box is not the letter — at line-height 1 a
   capital occupies roughly 14% to 86% of it, which is why the thirds land at 38% and 62%
   rather than 33% and 67%. */
.fc-logo { display: inline-flex; align-items: center; line-height: 1; white-space: nowrap; }
.fc-word {
  font-weight: 800;
  font-size: var(--fc-logo-size, 1.6rem);
  letter-spacing: -.02em;
  color: var(--ink);
}
/* A hair of air between the banded numeral and the word, so the 3 reads as its own block. */
.fc-word > .fc-tri:first-child { margin-right: .03em; }
.fc-word > .fc-tri:not(:first-child) { margin-left: .04em; }
.fc-tri {
  display: inline-block;
  line-height: 1;
  background-image: linear-gradient(
    var(--fc-a) 0 38%, var(--fc-b) 38% 62%, var(--fc-c) 62% 100%);
  -webkit-background-clip: text;
          background-clip: text;
  /* Safari needs the prefixed fill as well, or the letter renders solid. */
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* The three bands, darkened for the light theme. The Travel Planner palette was drawn for
   a black ground only; on white its amber all but disappears, so light mode keeps the hues
   and takes them several steps down. */
:root {
  --fc-a: #2563EB;
  --fc-b: #7C3AED;
  --fc-c: #B45309;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --fc-a: #60A5FA; --fc-b: #A78BFA; --fc-c: #FBBF24; }
}
:root[data-theme="dark"] { --fc-a: #60A5FA; --fc-b: #A78BFA; --fc-c: #FBBF24; }

/* Where background-clip:text is not supported the letter would be invisible, not merely
   unstyled, so it falls back to the middle band as a flat colour. */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .fc-tri { -webkit-text-fill-color: var(--fc-b); color: var(--fc-b); background-image: none; }
}

/* ---- week and day, as a time grid ------------------------------------------------------ */
/* --cols is the number of day columns: seven for the tablet week, one for the day at any
   size. The phone's week falls back to the stacked list below, because seven columns of a
   24-hour grid at 400px is unreadable; one column is fine. */
.weekgrid {
  --gutter: 3.4rem;
  --hour: 3rem;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.wheads {
  display: grid;
  grid-template-columns: var(--gutter) repeat(var(--cols, 7), 1fr);
  border-bottom: 1px solid var(--line);
}
/* The day's grid: the bar above already names the day, so no heading row. */
.weekgrid.single .wheads { display: none; }
.weekgrid.single .wcol { border-left: 1px solid var(--line); }
.wheads .colhead {
  border: 0;
  border-left: 1px solid var(--line);
  background: transparent;
  font: inherit;
  color: inherit;
  cursor: pointer;
  padding: .35rem .45rem;
  text-align: left;
}
.wheads .colhead .dow { font-size: .68rem; color: var(--muted); text-transform: uppercase; }
.wheads .colhead .dnum { font-size: 1.05rem; font-weight: 650; }
.wheads .colhead.today .dnum { color: var(--today-ink); }

/* All-day and multi-day events, above the clock. Same lanes as the month grid. */
.wstrip {
  min-height: calc(var(--lanes, 1) * 1.2rem + .4rem);
  border-bottom: 1px solid var(--line);
}
/* In the strip the bar layer is in normal flow, not floated over cells as in the month:
   the strip then is exactly as tall as its lanes and nothing can clip. */
.wstrip .spans { position: static; margin: .2rem 0 .2rem var(--gutter); }

.wbody {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: grid;
  grid-template-columns: var(--gutter) 1fr;
}
.hours { display: grid; grid-auto-rows: var(--hour); }
.hours span {
  font-size: .68rem;
  color: var(--muted);
  text-align: right;
  padding-right: .4rem;
  font-variant-numeric: tabular-nums;
  /* Sits the label on its hour line rather than in the middle of the hour below it. */
  transform: translateY(-.4em);
}
.wcols {
  display: grid;
  grid-template-columns: repeat(var(--cols, 7), 1fr);
  /* One hour line for the whole week, painted once instead of per column. */
  background: repeating-linear-gradient(to bottom, var(--line) 0 1px, transparent 1px var(--hour));
}
.wcol {
  position: relative;
  border-left: 1px solid var(--line);
  height: calc(24 * var(--hour));
}
.wcol.today { background: color-mix(in srgb, var(--today) 60%, transparent); }
.slot {
  position: absolute;
  display: flex;
  flex-direction: column;
  border: 0;
  border-left: 3px solid var(--accent);
  border-radius: 3px;
  background: color-mix(in srgb, var(--accent) 22%, var(--panel));
  padding: .05rem .28rem;
  font: inherit;
  font-size: .7rem;
  line-height: 1.15;
  color: inherit;
  text-align: left;
  /* A button centres its content by default, which in a full-width day column puts the
     time and title in the middle of the block. Everything starts at the left edge. */
  align-items: flex-start;
  justify-content: flex-start;
  overflow: hidden;
  cursor: pointer;
}
.slot.unassigned { --accent: var(--unassigned); }
/* Square top on a block that is the tail of something that began the day before, so it
   reads as carried over rather than as starting at midnight. */
.slot.continued { border-top-left-radius: 0; border-top-right-radius: 0; }
.slot.short { flex-direction: row; align-items: baseline; gap: .3rem; }
.slot.short .what { flex: 1; }
.slot .when { color: var(--muted); font-variant-numeric: tabular-nums; flex: none; }
.slot .what { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- week and day --------------------------------------------------------------------- */
.week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px;
        background: var(--line); border: 1px solid var(--line);
        border-radius: var(--radius); overflow: hidden; flex: 1; min-height: 0; }
.week .col { background: var(--panel); display: flex; flex-direction: column; }
.week .col.today { background: var(--today); }
.week .colhead {
  border: 0; background: transparent; font: inherit; cursor: pointer;
  padding: .4rem; text-align: left; border-bottom: 1px solid var(--line);
}
.week .colhead .dow { font-size: .68rem; color: var(--muted); text-transform: uppercase; }
.week .colhead .dnum { font-size: 1.05rem; font-weight: 650; }
.week .col .items { padding: .3rem; display: flex; flex-direction: column; gap: .2rem; }

.agenda { display: flex; flex-direction: column; gap: .3rem; max-width: 46rem; margin: 0 auto; }
.agenda .row {
  display: flex;
  gap: .7rem;
  align-items: flex-start;
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
  padding: .5rem .7rem;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  width: 100%;
}
.agenda .row.unassigned { --accent: var(--unassigned); }
.agenda .row:hover { border-color: var(--accent); }
.agenda .time { font-variant-numeric: tabular-nums; color: var(--muted); min-width: 6.5rem; flex: none; }
.agenda .body { min-width: 0; }
.agenda .what { font-weight: 600; }
.agenda .meta { color: var(--muted); font-size: .82rem; }
.empty { color: var(--muted); text-align: center; padding: 2rem 1rem; }

/* ---- the day overlay ------------------------------------------------------------------ */
/* Sits over the calendar rather than replacing it: the month or year behind stays exactly
   where it was, so closing returns you there with no reload and no lost scroll. */
.daypanel {
  position: fixed;
  z-index: 30;
  inset: auto;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(46rem, 94vw);
  max-height: min(80dvh, 46rem);
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  box-shadow: var(--shadow);
  overflow: hidden;
}
.daypanel-head {
  display: flex;
  align-items: center;
  gap: .4rem;
  padding: .55rem .7rem;
  border-bottom: 1px solid var(--line);
  background: var(--panel-2);
}
.daypanel-head h2 { font-size: .98rem; margin: 0; white-space: nowrap;
                    overflow: hidden; text-overflow: ellipsis; }
.daypanel-body { padding: .7rem; overflow: auto; }

/* ---- drawer, scrim, curtains ----------------------------------------------------------- */
.drawer {
  position: fixed;
  z-index: 40;
  top: 0;
  right: 0;
  height: 100dvh;
  width: min(22rem, 92vw);
  background: var(--panel);
  border-left: 1px solid var(--line);
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
}
.drawer-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: .7rem; border-bottom: 1px solid var(--line);
}
.drawer-head h2 { margin: 0; font-size: 1rem; }
.drawer-body { overflow: auto; padding: .8rem; display: flex; flex-direction: column; gap: 1.2rem; }
.drawer-body h3 { margin: 0 0 .45rem; font-size: .78rem; text-transform: uppercase;
                  letter-spacing: .05em; color: var(--muted); }
.choices { display: flex; gap: .35rem; flex-wrap: wrap; }
.choices button[aria-pressed="true"] { background: var(--accent); border-color: var(--accent);
                                        color: var(--accent-ink); }

.scrim { position: fixed; inset: 0; z-index: 20; background: rgba(0, 0, 0, .42); }

.curtain {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  background: var(--bg);
  padding: 1.5rem;
}
.signin-card {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 1.6rem;
  width: min(26rem, 100%);
  text-align: center;
}
.signin-card h1 { margin: 0 0 .5rem; font-size: 1.25rem; }
.signin-detail {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .78rem;
  color: var(--muted);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .5rem;
  word-break: break-word;
}
.signin-actions { display: flex; gap: .5rem; justify-content: center; margin-top: 1rem; flex-wrap: wrap; }

/* One button, top right of the card, cycling System → Light → Dark.
   Deliberately quiet: no border, no background, and text mixed 40% toward the page so it
   sits well behind the sign-in itself. It is a setting, not a step. */
.theme-cycle {
  position: absolute;
  top: .6rem;
  right: .7rem;
  border: 0;
  background: none;
  padding: .25rem .4rem;
  font: inherit;
  font-size: .78rem;
  color: color-mix(in srgb, var(--muted) 60%, var(--bg));
  cursor: pointer;
  border-radius: 6px;
}
.theme-cycle:hover,
.theme-cycle:focus-visible { color: var(--muted); background: var(--panel-2); }

/* The join, sign-in and register forms. Left-aligned inside a centred card, because a
   centred label above a full-width field reads as decoration rather than as a form. */
.signin-form { display: flex; flex-direction: column; gap: .6rem; margin-top: 1rem; text-align: left; }
.signin-form label { display: flex; flex-direction: column; gap: .25rem; font-size: .85rem; color: var(--muted); }
.signin-form input { width: 100%; }
.signin-form input[name=code] {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.signin-form button { margin-top: .2rem; }

/* ---- invitations ------------------------------------------------------------------------ */
.invite-list { list-style: none; margin: 0 0 .7rem; padding: 0; }
.invite-list li { display: flex; align-items: center; gap: .5rem; padding: .3rem 0; }
/* Takes the slack so the withdraw button sits at the right edge and the row stays on one
   line. Without it the three parts wrap and every invitation reads as two. */
.invite-list li .muted { flex: 1; min-width: 0; font-size: .8rem; }
.invite-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .85rem;
  letter-spacing: .06em;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .15rem .4rem;
  /* Selectable in one gesture: this exists to be copied into a message. */
  user-select: all;
}

/* ---- members --------------------------------------------------------------------------- */
.member-list { list-style: none; margin: 0 0 .7rem; padding: 0; }
.member-list li { display: flex; align-items: center; gap: .5rem; padding: .25rem 0; }
.member-list .dot { width: .85rem; height: .85rem; }
.member-list .name { flex: 1; }
.member-add { display: flex; gap: .35rem; }
.member-add input[name=name] { flex: 1; min-width: 0; }
.member-add input[type=color] { width: 2.5rem; padding: .15rem; }

/* ---- dialog ---------------------------------------------------------------------------- */
dialog {
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  background: var(--panel);
  color: var(--ink);
  padding: 1.1rem;
  width: min(28rem, 94vw);
  box-shadow: var(--shadow);
}
dialog::backdrop { background: rgba(0, 0, 0, .5); }
dialog h2 { margin: 0 0 .8rem; font-size: 1.02rem; }
dialog label { display: block; margin-bottom: .6rem; font-size: .82rem; color: var(--muted); }
dialog label.row { display: flex; align-items: center; gap: .45rem; color: var(--ink); }
input, select, textarea {
  display: block; width: 100%; margin-top: .2rem; padding: .45rem .55rem;
  font: inherit; color: var(--ink); background: var(--bg);
  border: 1px solid var(--line-strong); border-radius: 8px;
}
dialog label.row input { width: auto; margin: 0; }
dialog menu { display: flex; gap: .5rem; align-items: center; margin: .9rem 0 0; padding: 0; }

/* ---- phone layout ----------------------------------------------------------------------
 * Driven by data-layout on <html>, which JS sets from the viewport unless overridden in
 * the menu. A media query alone could not honour that override. */
html[data-layout="phone"] .app { grid-template-rows: auto 1fr auto; }
html[data-layout="phone"] .topbar .zoombar { display: none; }
html[data-layout="phone"] .phone-zoom {
  display: flex;
  border: 0;
  border-top: 1px solid var(--line);
  border-radius: 0;
  background: var(--panel);
  padding-bottom: env(safe-area-inset-bottom);
}
html[data-layout="phone"] .phone-zoom button { flex: 1; justify-content: center; padding: .7rem 0; }
html[data-layout="phone"] .bar-nav h1 { font-size: .95rem; margin-left: .3rem; }
html[data-layout="phone"] #today { display: none; }
html[data-layout="phone"] .add-long { display: none; }
html[data-layout="phone"] .add { padding: .4rem .6rem; font-size: 1.05rem; }
html[data-layout="phone"] .identity span:not(.dot) { display: none; }
html[data-layout="phone"] .identity { max-width: none; }
html[data-layout="phone"] .canvas { padding: 6px; }
html[data-layout="phone"] .year { grid-template-columns: repeat(2, 1fr); }
html[data-layout="phone"] .day { min-height: 3.6rem; }
html[data-layout="phone"] .grid { grid-auto-rows: minmax(3.6rem, 1fr); }
html[data-layout="phone"] .chip .when { display: none; }
html[data-layout="phone"] .daypanel {
  inset: auto 0 0 0;
  left: 0; top: auto;
  transform: none;
  width: 100%;
  max-height: 88dvh;
  border-radius: 14px 14px 0 0;
  padding-bottom: env(safe-area-inset-bottom);
}
html[data-layout="phone"] #dayZoom { display: none; }
html[data-layout="phone"] .agenda .time { min-width: 4.6rem; }

/* The week view cannot honestly hold seven columns on a phone, so it stacks into seven
   equal rows that together fill the pane, each day's events scrolling inside its row. */
html[data-layout="phone"] .week {
  grid-template-columns: 1fr;
  /* Seven equal rows that share the pane; on a very short screen each keeps room for its
     heading and one event and the pane scrolls instead of the rows collapsing. */
  grid-template-rows: repeat(7, minmax(4.4rem, 1fr));
  flex: 1 0 auto;
  min-height: 0;
}
html[data-layout="phone"] .week .col { min-height: 0; overflow: hidden; }
html[data-layout="phone"] .week .colhead { display: flex; align-items: baseline; gap: .5rem; padding: .3rem .45rem; }
html[data-layout="phone"] .week .col .items { flex: 1; min-height: 0; overflow-y: auto; }
html[data-layout="phone"] .week .col:not(.has-events) .items { display: none; }
/* The day's hour grid at phone width: a little tighter, and a narrower gutter. */
html[data-layout="phone"] .weekgrid { --gutter: 3rem; --hour: 2.8rem; }

html[data-layout="tablet"] .add-short { display: none; }

/* ---- sign-up, invitations, ownership (2026-09-20) --------------------------------------
 * Everything the auth brief added. Same tokens as the rest; three additions: the owner pill
 * in the mark's amber band, a pending state on the today pair, and a green for "done". */
:root { --ok: #1f8a4c; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --ok: #4ade80; } }
:root[data-theme="dark"] { --ok: #4ade80; }

.signin-card { text-align: center; }
.card-title { margin: .2rem 0 .3rem; font-size: 1.15rem; letter-spacing: -.01em; }
.signin-form .card-title, .signin-form .sub, .signin-form .eyebrow { text-align: center; }
.sub { color: var(--muted); font-size: .85rem; margin: 0 0 .6rem; }
.eyebrow { font-size: .7rem; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); margin: 0; }
.hint { font-size: .75rem; color: var(--muted); margin: -.2rem 0 0; }
.foot { margin: 1rem 0 0; font-size: .8rem; color: var(--muted); }
.foot a, .foot button { color: var(--accent); background: none; border: 0; padding: 0; font: inherit; cursor: pointer; text-decoration: none; }
.back-link {
  position: absolute; top: .6rem; left: .7rem; border: 0; background: none; padding: .25rem .4rem;
  font: inherit; font-size: .78rem; color: var(--muted); cursor: pointer; border-radius: 6px;
}
.divider { display: flex; align-items: center; gap: .6rem; color: var(--muted); font-size: .75rem; margin: .4rem 0; }
.divider::before, .divider::after { content: ""; flex: 1; border-top: 1px solid var(--line); }
.providers { display: flex; flex-direction: column; gap: .5rem; }
.providers button { justify-content: center; }

.field { display: flex; flex-direction: column; gap: .35rem; text-align: left; }
.field-label { font-size: .85rem; color: var(--muted); }
.swatches { display: flex; gap: .5rem; flex-wrap: wrap; }
.sw { width: 30px; height: 30px; border-radius: 50%; border: 3px solid transparent; padding: 0; cursor: pointer; }
.sw[aria-pressed="true"] { border-color: var(--ink); box-shadow: inset 0 0 0 2px var(--panel); }
.row-check { flex-direction: row !important; align-items: center; gap: .5rem; color: var(--ink) !important; }
/* The "as the owner you can" list on the accept panel. Not `.what`: that is the label
   inside every event bar, chip and slot, and giving this list that name pushed every
   event label up out of its box for a morning. */
.owner-can { text-align: left; font-size: .85rem; margin: 0 0 .8rem; padding-left: 1.1rem; color: var(--muted); }
.owner-can li { margin-bottom: .15rem; }

/* Attention, not alarm: the today pair. `.bad` is for a refusal. */
.banner {
  display: flex; gap: .6rem; align-items: flex-start; text-align: left;
  background: var(--today); color: var(--today-ink); border-radius: 10px;
  padding: .6rem .75rem; font-size: .82rem; margin: 0 0 .8rem;
}
.banner.bad { background: color-mix(in srgb, var(--danger) 12%, var(--panel)); color: var(--danger); }
.banner.ok { background: color-mix(in srgb, var(--ok) 14%, var(--panel)); color: var(--ok); }
.banner .grow { flex: 1; }
.banner button { border-color: currentColor; color: inherit; background: transparent; padding: .25rem .55rem; font-size: .78rem; flex: none; }

.pill {
  font-size: .68rem; padding: .08em .55em; border-radius: 999px; border: 1px solid var(--line-strong);
  color: var(--muted); white-space: nowrap; flex: none;
}
.pill.owner {
  color: var(--fc-c); border-color: color-mix(in srgb, var(--fc-c) 45%, transparent);
  background: color-mix(in srgb, var(--fc-c) 12%, transparent); font-weight: 600;
}
.pill.you { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.pill.pending { color: var(--today-ink); background: var(--today); border-color: transparent; }

.row { display: flex; align-items: center; gap: .6rem; padding: .45rem 0; font-size: .92rem; }
.row .grow, .rowbtn .grow { flex: 1; min-width: 0; text-align: left; }
.row .sub, .rowbtn .sub, .calendar-list .sub { display: block; font-size: .76rem; color: var(--muted); margin: 0; }
.chev { color: var(--muted); }
.rowbtn {
  width: 100%; display: flex; align-items: center; gap: .6rem; text-align: left;
  background: var(--panel-2); border-color: var(--line); padding: .55rem .7rem;
}
.rowbtn b { font-weight: 600; }
.btn-row { display: flex; gap: .4rem; flex-wrap: wrap; }
.btn-row button { flex: 1; justify-content: center; }

.calendar-list { list-style: none; margin: 0 0 .5rem; padding: 0; }
.calendar-list li { display: flex; align-items: center; gap: .5rem; padding: .45rem .4rem; border-radius: 8px; }
.calendar-list li.current { background: var(--panel-2); }
.calendar-list .name { flex: 1; min-width: 0; text-align: left; }
.calendar-list .tick { color: var(--ok); font-weight: 700; width: 1.2rem; text-align: center; flex: none; }
.calendar-list button { padding: .25rem .55rem; font-size: .78rem; }

.member-list li { padding: .35rem 0; }
.member-list li.clickable { cursor: pointer; border-radius: 8px; }
.member-list li.clickable:hover { background: var(--panel-2); }
.member-list .name .sub { display: block; }
.choices-list li { gap: .6rem; }
.choices-list li.disabled { opacity: .5; }
.radio { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--line-strong); flex: none; }
.radio[aria-checked="true"] { border-color: var(--accent); background: var(--accent); box-shadow: inset 0 0 0 4px var(--panel); }

.invite-list li { flex-wrap: wrap; }
.invite-list .who { flex: 1; min-width: 0; text-align: left; font-size: .88rem; }
.invite-list .who .sub { display: block; font-size: .76rem; color: var(--muted); }
.invite-list li button { padding: .25rem .55rem; font-size: .78rem; }

dialog .hint { margin: -.3rem 0 .6rem; }
dialog .field { margin-bottom: .6rem; }
dialog .field-label { font-size: .82rem; }
dialog h2 { margin: 0 0 .4rem; font-size: 1.05rem; }
dialog p.muted { margin: 0 0 .8rem; }
#confirmText { margin: 0 0 1rem; }

/* ---- the day picker (2026-09-20) ------------------------------------------------------
 * Reid asked for the day's title to be a drop-down of the seven days either side. It is a
 * native <select> dressed as the heading it replaces, so phones get their own picker. */
.daypick {
  font: inherit; font-weight: 700; font-size: 1rem; color: var(--ink);
  background: var(--panel); border: 1px solid var(--line-strong); border-radius: 8px;
  padding: .3rem 1.6rem .3rem .55rem; max-width: 100%; min-width: 0;
  appearance: none; -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: right .85rem center, right .55rem center;
  background-size: .3rem .3rem, .3rem .3rem; background-repeat: no-repeat;
}
.daypanel-head .daypick { flex: 0 1 auto; min-width: 0; }
.bar-nav .daypick { margin-left: .3rem; flex: 0 1 auto; }
html[data-layout="phone"] .daypick { font-size: .95rem; }
