/* Tokens taken from the Alter Mobile mockup, which inverts the Modernist
   design system for dark. The accent values are that system's ramp:
   #ff563c is --color-accent-500, #ec3013 is --color-accent, and the light
   ground #f3f2f2 becomes the text colour here. */
:root {
  --ground: #0a0908;
  --raised: rgba(243, 242, 242, 0.045);
  --raised-hover: rgba(243, 242, 242, 0.08);
  --hairline: rgba(243, 242, 242, 0.07);
  --text: #f3f2f2;
  --muted: rgba(243, 242, 242, 0.5);
  --faint: rgba(243, 242, 242, 0.35);
  --accent: #ff563c;
  --accent-press: #ec3013;
  --font: 'Archivo', system-ui, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  background: radial-gradient(1200px 800px at 50% 0%, #171210 0%, var(--ground) 70%);
  background-attachment: fixed;
  color: var(--text);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
[hidden] { display: none !important; }

/* ── brand ─────────────────────────────────────────────────── */
.brand { display: flex; align-items: center; gap: 10px; }
.brand-name { font-weight: 800; font-size: 17px; letter-spacing: 0.1em; }
.brand-sub { font-weight: 600; font-size: 9px; letter-spacing: 0.14em; color: var(--accent); }

.orb {
  width: 34px; height: 34px; flex: none;
  border-radius: 99px; display: grid; place-items: center;
  background: radial-gradient(circle at 40% 35%, #ff563c 0%, #ec3013 45%, #7a1608 100%);
  box-shadow: 0 0 20px rgba(236, 48, 19, 0.55);
}
.orb-core {
  width: 6px; height: 6px; border-radius: 99px; background: #fff;
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 0.55; transform: scale(1); }
  50%      { opacity: 1;    transform: scale(1.15); }
}
@media (prefers-reduced-motion: reduce) {
  .orb-core { animation: none; opacity: 1; }
  .progress-bar { transition: none; }
}

/* ── buttons ───────────────────────────────────────────────── */
.btn-primary, .btn-secondary, .btn-quiet, .btn-ghost, .btn-icon {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  font-family: var(--font); font-weight: 700; font-size: 13px;
  border-radius: 14px; border: 1px solid transparent;
  cursor: pointer; color: var(--text);
}
.btn-primary, .btn-secondary { padding: 12px 18px; }
.btn-primary {
  background: linear-gradient(160deg, #ec3013 0%, #a81f0b 100%);
  box-shadow: 0 8px 28px rgba(236, 48, 19, 0.35); color: #fff;
}
.btn-primary:hover:not(:disabled)  { filter: brightness(1.08); }
.btn-primary:active:not(:disabled) { transform: scale(0.97); }
.btn-secondary { background: var(--raised); border-color: rgba(243, 242, 242, 0.09); }
.btn-secondary:hover:not(:disabled) { background: var(--raised-hover); }
.btn-secondary:active:not(:disabled) { transform: scale(0.97); }
.btn-quiet {
  background: none; color: var(--muted); font-weight: 600; padding: 10px 0;
  justify-content: flex-start;
}
.btn-quiet:hover { color: var(--text); }
.btn-ghost { background: none; color: var(--accent); padding: 8px 4px; }
.btn-ghost:hover:not(:disabled) { color: var(--accent-press); }
.btn-icon {
  width: 34px; height: 34px; padding: 0; flex: none; border-radius: 99px;
  background: var(--raised); border-color: rgba(243, 242, 242, 0.09);
}
.btn-icon:hover { background: var(--raised-hover); }
.btn-wide { width: 100%; padding: 15px; font-size: 14px; }
button:disabled { opacity: 0.45; cursor: not-allowed; }

/* ── login ─────────────────────────────────────────────────── */
.login { min-height: 100vh; display: grid; place-items: center; padding: 32px 20px; }
.login-card { width: 100%; max-width: 360px; display: flex; flex-direction: column; gap: 28px; }
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.field label {
  font-size: 10px; font-weight: 600; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--faint);
}
.field input {
  width: 100%; padding: 14px 16px; border-radius: 14px;
  background: var(--raised); border: 1px solid var(--hairline);
  color: var(--text);
  /* 16px keeps iOS Safari from zooming the page when the field takes focus. */
  font: 400 16px var(--font);
  caret-color: var(--accent);
}
.field input:focus { border-color: rgba(236, 48, 19, 0.55); outline: none; }
.error {
  margin: 0 0 14px; padding: 12px 14px; border-radius: 12px; font-size: 12.5px;
  background: rgba(236, 48, 19, 0.1); border: 1px solid rgba(236, 48, 19, 0.35);
  color: var(--accent);
}
.login-foot { margin: 0; font-size: 11px; color: var(--faint); text-align: center; }

/* ── app shell ─────────────────────────────────────────────── */
.app { min-height: 100vh; display: flex; flex-direction: column; }

/* On a phone the sidebar is a header: brand row, then the sections as a
   horizontally scrolling strip of pills. It becomes a real column at 900px. */
.sidebar {
  display: flex; flex-direction: column; gap: 14px;
  padding: max(18px, env(safe-area-inset-top)) 0 12px;
  border-bottom: 1px solid var(--hairline);
}
.side-top { display: flex; align-items: center; gap: 16px; padding: 0 20px; }
.side-top .btn-quiet { margin-left: auto; padding: 0; font-size: 12px; }
.sidebar .side-spacer, .sidebar .gideon-card { display: none; }

.side-nav {
  display: flex; gap: 8px; overflow-x: auto; padding: 2px 20px;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.side-nav::-webkit-scrollbar { display: none; }
.nav-kicker { display: none; }

.nav-row {
  display: inline-flex; align-items: center; gap: 8px; flex: none;
  padding: 8px 14px; border-radius: 99px; cursor: pointer;
  background: var(--raised); border: 1px solid rgba(243, 242, 242, 0.09);
  color: rgba(243, 242, 242, 0.75);
  /* A button centres its text by default, which pushes the class names off
     the icons they sit beside. */
  font: 600 12.5px var(--font); white-space: nowrap; text-align: left;
}
.nav-row:hover { background: var(--raised-hover); }
.nav-row.is-on {
  background: rgba(236, 48, 19, 0.12);
  border-color: rgba(236, 48, 19, 0.35); color: var(--accent);
}
.nav-dot { width: 8px; height: 8px; flex: none; border-radius: 99px; }
.nav-badge {
  font: 700 9px var(--font); color: var(--accent);
  background: rgba(236, 48, 19, 0.14); border-radius: 99px; padding: 3px 7px;
}

.gideon-card {
  border-radius: 14px; padding: 14px;
  background: rgba(236, 48, 19, 0.09); border: 1px solid rgba(236, 48, 19, 0.3);
}
.gideon-label {
  font: 600 9.5px var(--font); letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 6px;
}
.gideon-text { margin: 0; font: 400 11.5px/1.5 var(--font); color: rgba(243, 242, 242, 0.7); }
.content {
  flex: 1; display: flex; flex-direction: column; gap: 26px;
  padding: 24px 20px max(28px, env(safe-area-inset-bottom));
}
.app-head { display: flex; flex-direction: column; gap: 18px; }
.app-head h1 { margin: 0; font-size: 28px; font-weight: 800; letter-spacing: -0.01em; }
.sub { margin: 5px 0 0; font-size: 13px; color: var(--muted); }
.actions { display: flex; gap: 10px; }
.actions button { flex: 1; }

.kicker {
  font-size: 10px; font-weight: 600; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--faint); margin-bottom: 12px;
}
.empty { margin: 0; font-size: 13px; color: var(--muted); }

/* ── upload feedback ───────────────────────────────────────── */
.status {
  padding: 13px 15px; border-radius: 14px; font-size: 12.5px; line-height: 1.45;
  background: var(--raised); border: 1px solid var(--hairline);
  word-break: break-word;
}
.status.is-error {
  background: rgba(236, 48, 19, 0.1);
  border-color: rgba(236, 48, 19, 0.35); color: var(--accent);
}
.status.is-done { border-color: rgba(236, 48, 19, 0.35); }
.progress {
  height: 6px; border-radius: 99px; overflow: hidden;
  background: rgba(243, 242, 242, 0.08);
}
.progress-bar {
  height: 100%; width: 0%; border-radius: 99px;
  background: linear-gradient(90deg, #ec3013, #ff563c);
  transition: width 0.2s ease;
}

/* ── captures ──────────────────────────────────────────────── */
.captures { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.capture {
  display: flex; align-items: flex-start; gap: 12px; padding: 14px 16px;
  border-radius: 16px; background: var(--raised); border: 1px solid var(--hairline);
}
.capture-kind {
  width: 28px; height: 28px; flex: none; border-radius: 9px; display: grid;
  place-items: center; background: rgba(236, 48, 19, 0.12);
  color: var(--accent); font-size: 9px; font-weight: 700;
}
.capture-title { font-size: 12.5px; font-weight: 600; line-height: 1.35; word-break: break-word; }
.capture-meta { font-size: 10.5px; color: var(--faint); margin-top: 3px; }

/* ── quick note ────────────────────────────────────────────── */
.note-head { display: flex; align-items: center; gap: 12px; }
.note-title {
  margin: 0; flex: 1; font-size: 15px; font-weight: 700; letter-spacing: 0.06em;
}
.note-box {
  display: flex; flex-direction: column; gap: 14px;
  border-radius: 20px; padding: 18px;
  background: rgba(243, 242, 242, 0.05);
  border: 1px solid rgba(236, 48, 19, 0.35);
  box-shadow: 0 0 32px rgba(236, 48, 19, 0.12);
}
.note-text {
  width: 100%; resize: vertical; min-height: 140px;
  background: none; border: none; outline: none; padding: 0;
  color: var(--text); font: 400 16px/1.5 var(--font);
  caret-color: var(--accent);
}
.note-text::placeholder { color: var(--faint); }
.note-foot {
  display: flex; align-items: center; gap: 8px;
  font-size: 11px; color: var(--muted);
}
.note-foot svg { flex: none; }

/* ── notes: one class ──────────────────────────────────────── */
.class-head { display: flex; align-items: center; gap: 14px; }
.class-dot {
  width: 14px; height: 14px; flex: none; border-radius: 99px;
  background: var(--accent);
}
.class-name { margin: 0; font-size: 24px; font-weight: 800; letter-spacing: -0.01em; }
.two-col { display: grid; gap: 26px; align-items: start; }

.notes, .sets { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.note-row {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 15px 16px; cursor: pointer; color: var(--text); font-family: var(--font);
  border-radius: 16px; background: var(--raised); border: 1px solid var(--hairline);
}
.note-row:hover { background: var(--raised-hover); }
.note-row:active { transform: scale(0.98); }
.note-icon {
  width: 28px; height: 28px; flex: none; border-radius: 9px; display: grid;
  place-items: center; background: rgba(236, 48, 19, 0.12);
}
.note-row-title { font: 600 14px/1.4 var(--font); }
.note-row-meta { font-size: 11px; color: var(--faint); margin-top: 3px; }

.set-row {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 16px; border-radius: 16px; cursor: pointer; color: var(--text);
  background: rgba(236, 48, 19, 0.08); border: 1px solid rgba(236, 48, 19, 0.3);
  font-family: var(--font);
}
.set-row:hover { background: rgba(236, 48, 19, 0.14); }
.set-row:active { transform: scale(0.98); }
.set-icon {
  width: 32px; height: 32px; flex: none; border-radius: 9px; display: grid;
  place-items: center; background: linear-gradient(160deg, #ec3013, #a81f0b);
}
.set-row-name { display: block; font: 700 14px var(--font); }
.set-row-count { display: block; font-size: 11px; color: var(--muted); margin-top: 2px; }
.set-grow { flex: 1; min-width: 0; }
.note-row-title, .note-row-meta { display: block; }

/* ── flashcards ────────────────────────────────────────────── */
.study { gap: 18px; }
.study-head { display: flex; align-items: center; gap: 14px; }
.study-titles { flex: 1; min-width: 0; }
.set-name { margin: 0; font-size: 20px; font-weight: 800; }
.study-head .sub { margin-top: 2px; font-size: 11.5px; }
.btn-small { padding: 9px 14px; font-size: 12px; border-radius: 12px; }

.study-active { flex: 1; display: flex; flex-direction: column; gap: 16px; }
.study-counts { display: flex; justify-content: space-between; margin-top: 8px; }
.count {
  font: 600 10.5px var(--font); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
}
.count.is-forgot { color: var(--accent); }
.count.is-known { color: rgba(243, 242, 242, 0.75); }

.card-stage {
  flex: 1; min-height: 260px; display: flex; align-items: center;
  justify-content: center; touch-action: pan-y; cursor: grab;
  /* Without this a drag across the card selects the term, and on iOS a long
     press raises the copy/define callout instead of moving the card. */
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
}
.card-stage:active { cursor: grabbing; }

/* The swipe layer. Perspective lives here rather than on the stage: this
   element takes a 2D transform while dragging, which would otherwise flatten
   the 3D flip happening on .card inside it. */
.card-swipe {
  position: relative; width: 100%; max-width: 640px; height: 100%;
  min-height: 260px; max-height: 380px; perspective: 1400px;
  transition: transform 0.25s cubic-bezier(0.32, 0.72, 0, 1), opacity 0.25s linear;
}
/* Under the finger there is no animation — the card is where you put it. */
.card-swipe.is-dragging { transition: none; }
.card-swipe.is-leaving {
  transition: transform 0.2s cubic-bezier(0.23, 1, 0.32, 1), opacity 0.2s linear;
}
/* A fresh card arrives rather than teleporting in behind the one that left. */
.card-swipe.is-entering { animation: card-in 0.2s cubic-bezier(0.23, 1, 0.32, 1); }
@keyframes card-in {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: none; }
}

/* Absolute rather than height:100%: on a phone the stage has no definite
   height, so a percentage resolves to auto and the faces collapse to a
   strip. inset:0 fills the swipe layer whatever its height turns out to be. */
.card {
  position: absolute; inset: 0; transform-style: preserve-3d;
  transition: transform 0.45s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.card.is-flipped { transform: rotateY(180deg); }

/* Which way you are throwing it. Opacity is set from the drag distance, so
   the label is fully lit exactly when letting go would count.
   Each label sits on the trailing edge — Forgot on the right, because
   dragging left would otherwise carry it off the side of a phone. */
.verdict {
  position: absolute; top: 18px; z-index: 2; opacity: 0; pointer-events: none;
  border-radius: 99px; padding: 8px 16px;
  font: 700 12px var(--font); letter-spacing: 0.08em; text-transform: uppercase;
}
.verdict.is-forgot {
  right: 18px; color: var(--accent);
  background: rgba(236, 48, 19, 0.16); border: 1.5px solid rgba(236, 48, 19, 0.65);
}
.verdict.is-known {
  left: 18px; color: var(--text);
  background: rgba(243, 242, 242, 0.12); border: 1.5px solid rgba(243, 242, 242, 0.5);
}
.card-face {
  position: absolute; inset: 0; backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  border-radius: 26px; padding: 32px; text-align: center;
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 16px;
}
.card-front {
  background: rgba(243, 242, 242, 0.05);
  border: 1px solid rgba(243, 242, 242, 0.12);
}
.card-back {
  transform: rotateY(180deg);
  background: rgba(236, 48, 19, 0.1);
  border: 1px solid rgba(236, 48, 19, 0.45);
  box-shadow: 0 0 32px rgba(236, 48, 19, 0.12);
}
.card-label {
  font: 600 10px var(--font); letter-spacing: 0.24em;
  text-transform: uppercase; color: var(--faint);
}
.card-label.is-accent { color: var(--accent); }
.card-term { font: 800 28px/1.25 var(--font); overflow-wrap: anywhere; }
.card-definition { font: 600 18px/1.5 var(--font); overflow-wrap: anywhere; }
.card-hint { font-size: 11.5px; color: var(--faint); }

.study-controls { display: flex; align-items: center; justify-content: center; gap: 18px; }
.btn-forgot, .btn-known {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 13px 22px; border-radius: 99px; cursor: pointer;
  font: 700 13px var(--font); font-family: var(--font);
}
.btn-forgot {
  color: var(--accent);
  background: rgba(236, 48, 19, 0.12); border: 1.5px solid rgba(236, 48, 19, 0.55);
}
.btn-forgot:hover { background: rgba(236, 48, 19, 0.22); }
.btn-known {
  color: var(--text);
  background: rgba(243, 242, 242, 0.08); border: 1.5px solid rgba(243, 242, 242, 0.4);
}
.btn-known:hover { background: rgba(243, 242, 242, 0.14); }
.btn-forgot:active, .btn-known:active { transform: scale(0.96); }
.btn-flip { width: 46px; height: 46px; color: rgba(243, 242, 242, 0.7); }
.study-hint { margin: 0; font-size: 11px; color: var(--faint); text-align: center; }

.study-done {
  flex: 1; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 22px; text-align: center;
}
.orb-large { width: 72px; height: 72px; }
.orb-large .orb-core { width: 14px; height: 14px; }
.done-title { margin: 0; font-size: 28px; font-weight: 800; }
.done-scores { display: flex; gap: 14px; width: 100%; max-width: 360px; }
.score {
  flex: 1; border-radius: 16px; padding: 16px;
  background: var(--raised); border: 1px solid rgba(243, 242, 242, 0.09);
}
.score.is-forgot {
  background: rgba(236, 48, 19, 0.09); border-color: rgba(236, 48, 19, 0.35);
}
.score-number { font: 800 30px var(--font); }
.score.is-forgot .score-number, .score.is-forgot .score-label { color: var(--accent); }
.score-label {
  font: 600 10px var(--font); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted); margin-top: 2px;
}
.done-actions {
  display: flex; flex-direction: column; gap: 10px; width: 100%; max-width: 360px;
}
.btn-centred { justify-content: center; }

/* ── one note, as a page ───────────────────────────────────── */
.notepage-head { display: flex; align-items: flex-start; gap: 12px; }
.notepage-titles { flex: 1; min-width: 0; }
.notepage-title {
  width: 100%; padding: 0; margin: 0; background: none; border: none;
  color: var(--text); font: 800 22px var(--font); letter-spacing: -0.01em;
  border-bottom: 1px solid transparent;
}
.notepage-title:focus { outline: none; border-bottom-color: rgba(236, 48, 19, 0.55); }
.notepage-title, .notepage-body { caret-color: var(--accent); }
.notepage-head .sub { margin-top: 4px; font-size: 11.5px; }
.notepage-state {
  flex: none; font: 600 9.5px var(--font); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted);
  background: var(--raised); border: 1px solid var(--hairline);
  border-radius: 99px; padding: 6px 11px; white-space: nowrap;
}
.notepage-state.is-edited {
  color: var(--accent);
  background: rgba(236, 48, 19, 0.1); border-color: rgba(236, 48, 19, 0.35);
}
.notepage-box { flex: 1; }
.notepage-body { flex: 1; min-height: 260px; resize: none; }

.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce) {
  /* Dragging still tracks the finger — that is direct manipulation, not
     animation. What goes is the travel: a card leaves by fading in place,
     and a fresh one does not scale up. The JS reads this too. */
  .card { transition: none; }
  .card-swipe, .card-swipe.is-leaving { transition: opacity 0.15s linear; }
  .card-swipe.is-entering { animation: none; }
  /* The name still has to be readable, so it arrives rather than travels. */
  .nav-label-text { transition: none; }
}

.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.seg { display: inline-flex; gap: 2px; padding: 2px; border-radius: 99px; background: var(--raised); }
.seg-btn {
  border: 0; cursor: pointer; padding: 5px 11px; border-radius: 99px;
  background: none; color: var(--muted); font: 600 11.5px var(--font);
}
.seg-btn.is-on { background: rgba(236, 48, 19, 0.14); color: var(--accent); }

.agenda-day { margin-top: 14px; }
.agenda-label {
  font: 600 9.5px var(--font); letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--faint); margin-bottom: 8px;
}
.agenda-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.agenda-item { display: flex; align-items: center; gap: 10px; }
.agenda-dot { width: 8px; height: 8px; flex: none; border-radius: 99px; }
.agenda-link {
  display: flex; flex: 1; min-width: 0; align-items: baseline; gap: 10px;
  color: inherit; text-decoration: none;
}
.agenda-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13.5px; }
.agenda-meta { flex: none; font-size: 11.5px; color: var(--muted); }
.agenda-item.is-done .agenda-title { color: var(--muted); text-decoration: line-through; }

/* ── google calendar, read only ────────────────────────────── */
/* Everything here is built from the tokens above and the panel/kicker/seg
   shapes the other screens use. The one new idea is the time column, and it
   exists because a calendar is read by its clock. */
.cal-account { display: flex; align-items: center; gap: 12px; }
.cal-readonly {
  font: 600 9.5px var(--font); letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted); background: var(--raised); border: 1px solid var(--hairline);
  border-radius: 99px; padding: 6px 11px; white-space: nowrap;
}
.cal-account .btn-quiet { padding: 0; font-size: 12px; }
.cal-connect { display: flex; flex-direction: column; gap: 14px; }
.cal-connect .kicker { margin-bottom: 0; }
.cal-connect .empty { line-height: 1.5; }
.cal-connect .error { margin: 0; }

.cal-sources { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.cal-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 11px; border-radius: 99px;
  background: var(--raised); border: 1px solid var(--hairline);
  font: 600 11px var(--font); color: var(--muted);
}
.cal-chip-name { max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cal-days { display: flex; flex-direction: column; gap: 18px; }

/* A week reads sideways.
 *
 * Seven days wrapped into a grid became three across and three down, so half
 * the week was below the fold and getting to Sunday meant scrolling the page
 * past Thursday. One row and a horizontal scroll puts the days in the order
 * they happen, and moving through them is the gesture the sidebar already uses.
 *
 * `align-items: start` is what keeps a quiet Tuesday from stretching itself to
 * match a busy Thursday: each column is as tall as its own day, and the strip
 * is as tall as the busiest one.
 *
 * The columns are deliberately narrower than the screen. With the scrollbar
 * hidden, the sliver of the next day is the only thing on screen saying there
 * is more to the right -- a full-width column would look tidier standing still
 * and give no hint the week continues.
 *
 * The negative margin lets the strip bleed to the edges of a screen whose
 * content is otherwise inset, so a day scrolls away off the edge rather than
 * stopping short of it. It must stay equal and opposite to `.content`'s
 * padding, here and in the wide-screen block below. */
.cal-days.is-week {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 78%;
  align-items: start;
  /* Seven fixed columns give this grid a min-content width of the whole week.
     Without this, that width propagates out to the flex column it sits in and
     the entire page scrolls sideways instead of the strip doing it -- which is
     the exact opposite of the point. */
  min-width: 0;
  gap: 14px;
  overflow-x: auto;
  /* Without this, swiping past the last day on a phone hands the gesture to
     the browser, which reads it as Back and leaves the calendar entirely. */
  overscroll-behavior-x: contain;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 0 20px;
  margin: 0 -20px;
}
.cal-days.is-week::-webkit-scrollbar { display: none; }
.cal-day-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding-bottom: 8px; border-bottom: 1px solid var(--hairline); margin-bottom: 10px;
}
.cal-day-label {
  font: 600 9.5px var(--font); letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--faint);
}
.cal-day-count { font: 600 10px var(--font); color: var(--faint); }
.cal-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.cal-none { margin: 0; font-size: 12.5px; color: var(--faint); }

/* No hover state, no pointer cursor, nothing that looks tappable: this row
   cannot be opened into an edit, and should not offer to be. */
.cal-event {
  display: flex; align-items: stretch; gap: 12px; padding: 12px 14px;
  border-radius: 14px; background: var(--raised); border: 1px solid var(--hairline);
}
.cal-time {
  flex: none; width: 72px; display: flex; flex-direction: column; gap: 2px;
}
.cal-time-start { font: 700 12.5px var(--font); }
.cal-time-end { font: 400 11px var(--font); color: var(--faint); }
.cal-event.is-all-day .cal-time-start {
  font-size: 10px; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--accent);
}
.cal-bar { flex: none; width: 3px; border-radius: 99px; background: var(--accent); }
.cal-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.cal-title { font: 600 13.5px/1.35 var(--font); overflow-wrap: anywhere; }
.cal-source {
  font-size: 10.5px; color: var(--faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.class-pick-list { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }
.class-pick-row {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 12px 14px; border-radius: 12px; cursor: pointer;
  background: var(--raised); border: 1px solid rgba(243, 242, 242, 0.09);
  color: inherit; font: 600 13.5px var(--font);
}
.class-pick-row:hover { background: var(--raised-hover); }
.class-pick-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── wide screens: the iPad layout ─────────────────────────── */
@media (min-width: 900px) {
  .app { flex-direction: row; align-items: stretch; }
  .sidebar {
    width: 264px; flex: none; align-items: stretch; gap: 22px;
    padding: 26px 20px; border-bottom: none; border-right: 1px solid var(--hairline);
    overflow-y: auto;
  }
  .side-top { padding: 0; }
  .sidebar .side-spacer { display: block; flex: 1; }
  .sidebar .gideon-card { display: block; }

  .side-nav { flex-direction: column; gap: 4px; overflow-x: visible; padding: 0; }
  .nav-kicker {
    display: block; margin: 14px 0 6px; padding: 0 12px;
    font: 600 9.5px var(--font); letter-spacing: 0.22em;
    text-transform: uppercase; color: var(--faint);
  }
  .nav-row {
    display: flex; padding: 10px 12px; border-radius: 12px;
    background: none; border: 1px solid transparent; font-size: 13px;
  }
  .nav-row:hover { background: rgba(243, 242, 242, 0.06); }
  .nav-row.is-on { border-color: transparent; }
  /* The 264px sidebar is the only place a class name can overflow. On the
     phone the nav is a scrolling strip of pills, where a wide pill is fine
     and truncating one would hide the name with nothing to reveal it. */
  .nav-row .nav-label {
    flex: 1;
    /* Without this a flex item refuses to shrink below its content, which is
       what pushed long names out through the side of the sidebar. */
    min-width: 0;
    overflow: hidden;
    /* Fades the clipped edge instead of an ellipsis: the text moves on hover,
       and an ellipsis sitting in the middle of moving text reads as a bug. */
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 16px), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 16px), transparent);
  }
  .nav-row .nav-label:not(.is-clipped) {
    -webkit-mask-image: none;
    mask-image: none;
  }
  .nav-label-text {
    display: inline-block;
    white-space: nowrap;
    transition: transform var(--nav-scroll-s, 0s) ease-in-out;
  }
  .nav-row:hover .is-clipped .nav-label-text,
  .nav-row:focus-visible .is-clipped .nav-label-text {
    transform: translateX(var(--nav-scroll-x, 0));
  }

  /* min-width: 0 because a flex item refuses by default to shrink below its
     content's own minimum, and the week strip's minimum is seven days wide.
     Beside a sidebar that made the page itself scroll sideways. */
  .content { padding: 30px 32px; gap: 28px; max-width: 1100px; min-width: 0; }
  .app-head { flex-direction: row; align-items: flex-end; justify-content: space-between; }
  .app-head h1 { font-size: 32px; }
  .actions { flex: none; }
  .actions button { flex: none; }
  .note-title { font-size: 17px; }

  .class-name { font-size: 26px; }
  .two-col { grid-template-columns: 1.25fr 1fr; }

  .study { padding-bottom: 26px; }
  .set-name { font-size: 22px; }
  .study-active { max-width: 760px; width: 100%; margin: 0 auto; }
  .card-stage { min-height: 300px; }
  .card-term { font-size: 32px; }
  .card-definition { font-size: 21px; }
  .study-controls { gap: 24px; }
  .card-face { padding: 40px; }

  .notepage-title { font-size: 26px; }
  .notepage-box { max-width: 760px; }

  /* Same one row, but sized so three or four days sit on screen at once
     rather than one very wide column with a lot of empty space in it.

     No edge bleed here. On the phone the strip runs to the edges of the screen
     because the screen is the whole layout; beside a sidebar it is not, and a
     negative margin there pushed the strip wider than the column it lives in
     and made the whole page scroll sideways. Three days already visible is
     affordance enough that the week continues. */
  .cal-days.is-week {
    grid-auto-columns: 260px;
    gap: 18px;
    padding: 0;
    margin: 0;
  }
  .cal-connect { max-width: 520px; }
}
