/* ============ Layout shell ============ */

html, body { height: 100%; }

body {
  font-family: var(--font-body);
  background: var(--color-bg);
  color: var(--color-text);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.layout {
  display: grid;
  grid-template-columns: minmax(280px, 20%) 1fr;
  flex: 1;
  min-height: 0; /* allow children to scroll inside the flex parent */
}

/* ============ Banner (migration prompt, etc.) ============ */

/* Full-width strip below the top bar, used right now only by the
   "import your local data" prompt after sign-in. Two-action layout:
   primary call-to-action + secondary 'keep separate' button. */
.banner {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--space-md);
  flex-wrap: wrap;
  padding: var(--space-md) var(--space-lg);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-surface-2);
}

.banner[hidden] { display: none; }

.banner__text {
  flex: 1;
  min-width: 16rem;
  font-size: var(--font-size-sm);
  color: var(--color-text);
  line-height: 1.5;
}

.banner__text strong {
  color: var(--color-text);
  font-weight: 600;
}

.banner__actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.banner__error {
  width: 100%;
  margin-top: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  background: rgba(255, 107, 107, 0.12);
  color: var(--color-danger);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-sm);
}

/* ============ Top bar ============ */

.topbar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  height: 2.75rem;
  padding: 0 var(--space-lg);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-surface-2);
}

.topbar__left,
.topbar__right {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

/* Bell icon — opens the notifications dropdown (see .notif-menu rules
   at the bottom of this file). Sits immediately left of the profile
   menu on every page. UINotifications wraps this button in a
   .notif-menu container at init for positioning the dropdown + badge. */
.topbar__bell {
  position: relative; /* anchors the unread badge */
  width: 2rem;
  height: 2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--color-text-muted);
  border-radius: 50%;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.topbar__bell:hover {
  background: var(--color-surface-2);
  color: var(--color-text);
}

.topbar__bell:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.topbar__left { flex: 1; }

.topbar__brand {
  font-size: var(--font-size-base);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text);
  line-height: 1;
  text-decoration: none;
  transition: color var(--transition-fast);
}

.topbar__brand:hover { color: var(--color-accent); }

/* Subtle vertical line between the two brand links. Intentionally
   low-contrast — its job is to group the brands as related nav
   without competing with their type. */
.topbar__brand-sep {
  display: inline-block;
  width: 1px;
  height: 1rem;
  background: var(--color-surface-2);
  align-self: center;
}

/* ----- Profile menu ----- */

.profile-menu {
  position: relative;
  display: flex;
  align-items: center;
}

.profile-menu__trigger {
  width: 2rem;
  height: 2rem;
  padding: 0;
  border-radius: 50%;
  overflow: hidden;
  background: transparent;
  color: var(--color-accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform var(--transition-fast), color var(--transition-fast);
}

.profile-menu__trigger:hover { color: var(--color-accent-hover); }
.profile-menu__trigger:active { transform: scale(0.96); }

.profile-menu__trigger:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.profile-menu__avatar {
  width: 100%;
  height: 100%;
  display: block;
}

/* Uploaded profile picture (a base64 data URL stored on
   auth.user_metadata.avatar_url). Filled to the trigger's circular
   bounds; the parent's overflow:hidden + border-radius clips it. */
.profile-menu__avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.profile-menu__dropdown {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 10rem;
  padding: var(--space-xs);
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--color-surface);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
  z-index: 20;
}

.profile-menu__dropdown[hidden] { display: none; }

.profile-menu__item {
  text-align: left;
  padding: var(--space-sm) var(--space-md);
  background: transparent;
  color: var(--color-text);
  font-size: var(--font-size-sm);
  border-radius: var(--radius-sm);
  transition: background var(--transition-fast);
}

.profile-menu__item:hover { background: var(--color-surface-2); }
.profile-menu__item:focus-visible {
  outline: none;
  background: var(--color-surface-2);
}

.profile-menu__item--danger { color: var(--color-danger); }
.profile-menu__item--danger:hover {
  background: var(--color-danger);
  color: var(--color-text);
}

/* Initials avatar shown in place of the silhouette when signed in.
   First letter of the email's local part in an accent-colored circle. */
.profile-menu__initials {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 600;
  text-transform: uppercase;
  user-select: none;
}

/* Header in the signed-in menu showing the user's email. Not a
   clickable item — purely informational. */
.profile-menu__user {
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--color-surface-2);
  margin-bottom: 2px;
}

.profile-menu__user-label {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  line-height: 1.2;
}

.profile-menu__user-email {
  font-size: var(--font-size-sm);
  color: var(--color-text);
  font-weight: 500;
  margin-top: 2px;
  word-break: break-all; /* long emails wrap rather than overflow */
}

/* When the dropdown holds the auth form (signed-out state), give it
   more breathing room than the compact menu form. */
.profile-menu__dropdown--auth {
  min-width: 18rem;
  padding: var(--space-sm);
}

/* Tabbed switch between Sign in and Create account modes. */
.auth-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px;
  margin-bottom: var(--space-sm);
  padding: 2px;
  background: var(--color-bg);
  border-radius: var(--radius-md);
}

.auth-tabs__btn {
  padding: var(--space-xs) var(--space-sm);
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  border-radius: var(--radius-sm);
  transition: background var(--transition-fast), color var(--transition-fast);
}

.auth-tabs__btn:hover {
  color: var(--color-text);
}

.auth-tabs__btn--active {
  background: var(--color-surface-2);
  color: var(--color-text);
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-xs) var(--space-sm) var(--space-sm);
}

.auth-form__title {
  font-size: var(--font-size-base);
  font-weight: 500;
  margin-bottom: var(--space-xs);
  padding: 0 var(--space-sm);
}

.auth-form__field {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.auth-form__label {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.auth-form__input {
  padding: var(--space-sm) var(--space-md);
  background: var(--color-bg);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--font-size-sm);
}

.auth-form__input:focus {
  outline: none;
  border-color: var(--color-accent);
}

.auth-form__submit {
  margin-top: var(--space-xs);
  width: 100%;
}

.auth-form__link {
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  text-align: center;
  padding: var(--space-xs);
  transition: color var(--transition-fast);
}

.auth-form__link:hover {
  color: var(--color-accent);
}

.auth-form__back {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  padding: var(--space-xs) var(--space-sm);
  margin-bottom: var(--space-xs);
  border-radius: var(--radius-sm);
  transition: color var(--transition-fast), background var(--transition-fast);
}

.auth-form__back:hover {
  color: var(--color-text);
  background: var(--color-surface-2);
}

.auth-form__message {
  font-size: var(--font-size-sm);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
  line-height: 1.4;
}

.auth-form__message[hidden] { display: none; }

.auth-form__message--info {
  background: rgba(78, 205, 196, 0.12);
  color: var(--color-success);
}

.auth-form__message--error {
  background: rgba(255, 107, 107, 0.12);
  color: var(--color-danger);
}

/* ============ Sidebar ============ */

.sidebar {
  background: var(--color-surface);
  border-right: 1px solid var(--color-surface-2);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  min-width: 0; /* allows children to shrink in narrow viewports */
  position: relative; /* anchor for the drag-to-remove overlay */
  /* Firefox: thumb / track colors with a thin scrollbar. */
  scrollbar-color: var(--color-surface-2) transparent;
  scrollbar-width: thin;
}

/* Chromium / WebKit equivalent. The thumb is the same surface-2 used
   for hover states elsewhere — a touch lighter than the sidebar
   background so it reads without clashing. */
.sidebar::-webkit-scrollbar {
  width: 8px;
}
.sidebar::-webkit-scrollbar-track {
  background: transparent;
}
.sidebar::-webkit-scrollbar-thumb {
  background: var(--color-surface-2);
  border-radius: 4px;
}
.sidebar::-webkit-scrollbar-thumb:hover {
  background: #3a3a66;
}

/* ----- Add-tool control (top of sidebar) ----- */

.add-tool {
  position: relative;
  padding: var(--space-md) var(--space-lg);
  border-bottom: 1px solid var(--color-surface-2);
}

.add-tool__btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  background: var(--color-surface-2);
  color: var(--color-text);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  font-weight: 500;
  transition: background var(--transition-fast);
}

.add-tool__btn:hover { background: #3a3a66; }

.add-tool__plus {
  font-size: 1.2em;
  line-height: 1;
  color: var(--color-accent);
}

.add-tool__menu {
  position: absolute;
  top: calc(100% - var(--space-sm));
  left: var(--space-lg);
  right: var(--space-lg);
  background: var(--color-surface);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-md);
  padding: var(--space-xs);
  display: flex;
  flex-direction: column;
  gap: 2px;
  z-index: 10;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
}

.add-tool__menu[hidden] { display: none; }

.add-tool__menu button {
  text-align: left;
  padding: var(--space-sm) var(--space-md);
  background: transparent;
  color: var(--color-text);
  font-size: var(--font-size-sm);
  border-radius: var(--radius-sm);
  transition: background var(--transition-fast);
}

.add-tool__menu button:hover { background: var(--color-surface-2); }

/* ----- Features (independently collapsible panels) ----- */

.features {
  display: flex;
  flex-direction: column;
}

.feature {
  border-bottom: 1px solid var(--color-surface-2);
}

.feature__header {
  position: relative; /* positioning context for the pencil edit menu */
  display: flex;
  align-items: stretch;
  gap: 0;
  background: transparent;
  color: var(--color-text);
}

/* Drag handle on the far left of each panel header. Only this element
   carries `draggable="true"` so accidental drags can't start from the
   rest of the panel. */
.feature__drag {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.25rem;
  padding: 0 0.25rem;
  color: var(--color-text-dim);
  font-size: 1.1rem;
  line-height: 1;
  cursor: grab;
  user-select: none;
  transition: color var(--transition-fast), background var(--transition-fast);
}

.feature__drag:hover {
  color: var(--color-text);
  background: var(--color-surface-2);
}

.feature__drag:active { cursor: grabbing; }

/* While the user is dragging this panel, fade it so the drop targets
   read as the live elements. */
.feature--dragging { opacity: 0.35; }

/* The floating ghost that follows the cursor during a drag. Built by
   cloning the source panel's header (the body is stripped). Pointer
   events are off so wheel/click target whatever is beneath, which lets
   the user scroll the sidebar with the wheel while dragging. */
.feature--ghost {
  pointer-events: none;
  background: var(--color-surface);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.5);
  opacity: 0.92;
  z-index: 1000;
}

/* Global cursor cue while a drag is in flight. */
body.dragging-feature,
body.dragging-feature * { cursor: grabbing !important; }

body.dragging-feature { user-select: none; }

/* Drop indicators on the target panel. A thin accent-colored line above
   or below the panel shows where the source will land on release. */
.feature--drop-before { box-shadow: inset 0 2px 0 var(--color-accent); }
.feature--drop-after  { box-shadow: inset 0 -2px 0 var(--color-accent); }

.feature__toggle {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md) var(--space-lg);
  background: transparent;
  color: var(--color-text);
  font-size: var(--font-size-base);
  font-weight: 500;
  text-align: left;
  transition: background var(--transition-fast);
}

.feature__toggle:hover { background: var(--color-surface-2); }

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

.feature__name-input {
  flex: 1;
  min-width: 0;
  padding: var(--space-xs) var(--space-sm);
  background: var(--color-bg);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-size: var(--font-size-base);
  font-weight: 500;
  font-family: var(--font-body);
}

.feature__name-input:focus { outline: none; }

.feature__meta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  color: var(--color-text-muted);
}

.feature__chevron {
  display: inline-block;
  transition: transform var(--transition-base);
  font-size: 0.8em;
}

.feature--open .feature__chevron { transform: rotate(180deg); }

.feature__icon-btn {
  flex: 0 0 auto;
  width: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-base);
  transition: background var(--transition-fast), color var(--transition-fast);
}

.feature__icon-btn:hover {
  background: var(--color-surface-2);
  color: var(--color-text);
}

.feature__close:hover {
  background: var(--color-danger);
  color: var(--color-text);
}

/* Pencil-icon edit menu. Right-aligned roughly under the pencil
   button (close button is 2rem; pencil sits just left of it). */
.feature__menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 2rem;
  min-width: 9rem;
  padding: var(--space-xs);
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--color-surface);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
  z-index: 50;
}

.feature__menu[hidden] { display: none; }

.feature__menu-item {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  width: 100%;
  padding: var(--space-sm) var(--space-md);
  background: transparent;
  color: var(--color-text);
  font-size: var(--font-size-sm);
  border-radius: var(--radius-sm);
  text-align: left;
  transition: background var(--transition-fast);
}

.feature__menu-item:hover { background: var(--color-surface-2); }

.feature__menu-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1em;
  color: var(--color-text-muted);
}

.feature__menu-dot {
  width: 0.75rem;
  height: 0.75rem;
  border-radius: 50%;
  background: var(--tool-color, var(--color-accent));
  flex: 0 0 auto;
}

.feature__menu-back {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* Color picker grid inside the recolor sub-menu. */
.feature__color-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-xs);
  padding: var(--space-xs);
}

.feature__color {
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform var(--transition-fast), border-color var(--transition-fast);
}

.feature__color:hover { transform: scale(1.12); }

.feature__color--current { border-color: var(--color-text); }

.feature__color:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Body is collapsed by default; opens when parent has .feature--open.
   max-height transition with a generous upper bound. */
.feature__body {
  max-height: 0;
  overflow: hidden;
  transition: max-height var(--transition-base), padding var(--transition-base);
  padding: 0 var(--space-lg);
}

.feature--open > .feature__body {
  max-height: 2000px;
  padding: 0 var(--space-lg) var(--space-lg);
}

/* Running indicator on the stopwatch header */

.sw-indicator {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-display);
  font-size: var(--font-size-sm);
  color: var(--tool-color, var(--color-accent));
  font-variant-numeric: tabular-nums;
}

.sw-indicator__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--tool-color, var(--color-accent));
  animation: blink 1.4s ease infinite;
}

/* While the current segment is a break, the time text on the collapsed
   indicator switches to the universal break color so it reads as
   "on break" at a glance. The dot keeps the stopwatch's color. */
.sw-indicator--on-break .sw-indicator__time {
  color: var(--color-break);
}

.sw-indicator--paused .sw-indicator__dot {
  animation: none;
  background: var(--color-text-muted);
}

.sw-indicator--paused,
.sw-indicator--paused .sw-indicator__time {
  color: var(--color-text-muted);
}

@keyframes blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

/* ============ Main content area ============ */

.main {
  padding: var(--space-xl);
  overflow-y: auto;
  min-width: 0;
}

/* ============ Buttons ============ */

.btn {
  padding: var(--space-sm) var(--space-md);
  background: var(--color-surface-2);
  color: var(--color-text);
  border-radius: var(--radius-md);
  font-weight: 500;
  transition: background var(--transition-fast), transform var(--transition-fast),
              opacity var(--transition-fast);
}

.btn:hover:not(:disabled)  { background: #3a3a66; }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled              { opacity: 0.5; }

.btn--primary             { background: var(--color-accent); }
.btn--primary:hover:not(:disabled) { background: var(--color-accent-hover); }
.btn--danger              { background: var(--color-danger); }
.btn--danger:hover:not(:disabled)  { background: var(--color-danger-hover); }
.btn--small               { padding: var(--space-xs) var(--space-sm); font-size: var(--font-size-sm); }

/* ============ Dots / legend ============ */

.dot {
  display: inline-block;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  vertical-align: middle;
  margin-right: 0.25rem;
}
/* Work-color elements follow `--tool-color` when an ancestor (panel
   section, or history row) sets it via inline style. Break stays
   universal. */
.dot--work  { background: var(--tool-color, var(--color-work)); }
.dot--break { background: var(--color-break); }

/* ============ Stopwatch internals ============ */

.stopwatch__display {
  font-family: var(--font-display);
  font-size: var(--font-size-display-md);
  font-weight: 300;
  font-variant-numeric: tabular-nums;
  text-align: center;
  letter-spacing: 0.04em;
  margin: var(--space-sm) 0 var(--space-md);
  transition: color var(--transition-base);
}

.stopwatch--on-break .stopwatch__display { color: var(--color-break); }

.stopwatch__breakdown {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-sm);
  background: var(--color-bg);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-md);
}

.breakdown__item {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.breakdown__label {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.breakdown__value {
  font-family: var(--font-display);
  font-size: var(--font-size-base);
  font-variant-numeric: tabular-nums;
}

.stopwatch__controls {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-bottom: var(--space-md);
}

.stopwatch__controls .btn { flex: 1 1 auto; }

.stopwatch__settings {
  border-top: 1px solid var(--color-surface-2);
  padding-top: var(--space-md);
}

.settings__row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-sm);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.settings__num {
  width: 3.5rem;
  padding: var(--space-xs) var(--space-sm);
  background: var(--color-bg);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-family: var(--font-display);
  text-align: center;
}

.settings__num:focus {
  outline: none;
  border-color: var(--color-accent);
}

/* Reminder banner */
.reminder {
  display: none;
  background: var(--color-warning);
  color: #2a1a00;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  margin-top: var(--space-md);
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  flex-wrap: wrap;
  animation: slideIn 200ms ease;
}

.reminder--visible { display: flex; }

.reminder__text { font-weight: 500; font-size: var(--font-size-sm); }
.reminder__actions { display: flex; gap: var(--space-xs); }
.reminder .btn { color: var(--color-text); }

@keyframes slideIn {
  from { transform: translateY(-4px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

/* ============ Timer internals ============ */

.timer__display {
  font-family: var(--font-display);
  font-size: var(--font-size-display-md);
  font-weight: 300;
  font-variant-numeric: tabular-nums;
  text-align: center;
  letter-spacing: 0.05em;
  margin: var(--space-sm) 0 var(--space-md);
}

.timer__inputs {
  display: flex;
  gap: var(--space-md);
  justify-content: center;
  margin-bottom: var(--space-md);
}

.timer__inputs label {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.timer__inputs input {
  width: 4rem;
  padding: var(--space-sm);
  background: var(--color-bg);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-sm);
  text-align: center;
  font-family: var(--font-display);
  font-size: var(--font-size-base);
  color: var(--color-text);
}

.timer__inputs input:focus {
  outline: none;
  border-color: var(--color-accent);
}

.timer__controls {
  display: flex;
  gap: var(--space-sm);
}

.timer__controls .btn { flex: 1 1 auto; }

.timer--finished .timer__display {
  color: var(--color-success);
  animation: pulse 1s ease infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.5; }
}

/* ============ History (main area) ============ */

.history {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.history__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-md);
  flex-wrap: wrap;
}

.history__title {
  font-size: var(--font-size-xl);
  font-weight: 500;
}

.history__actions {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  flex-wrap: wrap;
}

.history__filter-wrap {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.history__filter {
  padding: var(--space-xs) var(--space-sm);
  background: var(--color-surface);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-size: var(--font-size-sm);
}

.history__filter:focus {
  outline: none;
  border-color: var(--color-accent);
}

.session__sw,
.tl-row__sw {
  color: var(--tool-color, var(--color-accent));
  font-weight: 500;
}

.tl-row__sw {
  font-size: var(--font-size-sm);
}

.view-toggle {
  display: inline-flex;
  background: var(--color-surface);
  border-radius: var(--radius-md);
  padding: 2px;
}

.view-toggle__btn {
  padding: var(--space-xs) var(--space-md);
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  border-radius: var(--radius-sm);
  transition: background var(--transition-fast), color var(--transition-fast);
}

.view-toggle__btn--active {
  background: var(--color-surface-2);
  color: var(--color-text);
}

.history__empty {
  text-align: center;
  color: var(--color-text-dim);
  padding: var(--space-2xl) 0;
  font-size: var(--font-size-base);
  background: var(--color-surface);
  border-radius: var(--radius-lg);
}

.history__content { display: flex; flex-direction: column; }

/* ----- List view ----- */

.session-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.session {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-md) var(--space-lg);
  background: var(--color-surface);
  border-radius: var(--radius-md);
  transition: background var(--transition-fast);
}

.session:hover { background: var(--color-surface-2); }

.session__when {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  min-width: 9rem;
}

.session__metrics {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.session__total {
  font-family: var(--font-display);
  font-size: var(--font-size-lg);
}

.session__detail {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.session__delete {
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: transparent;
  color: var(--color-text-dim);
  font-size: 1.25rem;
  line-height: 1;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.session__delete:hover {
  background: var(--color-danger);
  color: var(--color-text);
}

/* ----- Timeline view ----- */

.timeline {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.tl-row {
  display: grid;
  grid-template-columns: 10rem 1fr auto;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-md) var(--space-lg);
  background: var(--color-surface);
  border-radius: var(--radius-md);
  transition: background var(--transition-fast);
}

.tl-row:hover { background: var(--color-surface-2); }

.tl-row__label {
  display: flex;
  flex-direction: column;
}

.tl-row__when {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.tl-row__total {
  font-family: var(--font-display);
  font-size: var(--font-size-base);
}

.tl-bar {
  display: flex;
  height: 2rem;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--color-bg);
}

.tl-bar__seg {
  height: 100%;
  transition: opacity var(--transition-fast);
}

.tl-bar__seg:hover { opacity: 0.85; }

.tl-bar__seg--work  { background: var(--tool-color, var(--color-work)); }
.tl-bar__seg--break { background: var(--color-break); }

/* ============ Week view (bar chart) ============ */

.week-view {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.week-view__header {
  display: flex;
  align-items: center;
  gap: var(--space-md);
}

.week-view__titles {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.week-view__range {
  font-size: var(--font-size-lg);
  font-weight: 500;
}

.week-view__sw {
  font-size: var(--font-size-sm);
  color: var(--tool-color, var(--color-accent));
  font-weight: 500;
}

.week-view__nav {
  width: 2.25rem;
  height: 2.25rem;
  background: var(--color-surface);
  color: var(--color-text);
  border-radius: 50%;
  font-size: 1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background var(--transition-fast);
}

.week-view__nav:hover { background: var(--color-surface-2); }

/* Chart grid:
   - column 1: y-axis labels
   - column 2: plot area (gridlines + bar columns)
   - row 1   : the chart itself (flex: 1)
   The container is `position: relative` so the special "0h" label can
   be absolutely positioned to sit in line with the day-label row. */
.week-chart {
  position: relative;
  display: grid;
  grid-template-columns: 2.25rem 1fr;
  grid-template-rows: 1fr;
  height: 18rem;
  padding: var(--space-md) 0 0;
  background: var(--color-surface);
  border-radius: var(--radius-md);
  padding-right: var(--space-md);
}

/* The "0h" baseline label. The other y-labels live inside
   .week-chart__y-axis and position by percent; "0h" doesn't fit that
   scheme because the y-axis container ends a label-row above the
   chart bottom. Pinning this one separately keeps it level with the
   day labels (Mon 4, Tue 5, …) instead of hanging in the gutter. */
.week-chart__zero {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 2.25rem;
  padding-right: var(--space-xs);
  padding-top: var(--space-xs);
  text-align: right;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

.week-chart__y-axis {
  position: relative;
  height: 100%;
  margin-bottom: 1.75rem; /* leave room for day labels under the plot */
}

.week-chart__y-label {
  position: absolute;
  right: var(--space-xs);
  transform: translateY(50%);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.week-chart__plot {
  position: relative;
  height: 100%;
  border-left: 1px solid var(--color-surface-2);
}

/* Dashed gridline at each hour. The thin dashed pattern uses a
   background gradient instead of an actual border so it doesn't
   shift bar heights. */
.week-chart__grid {
  position: absolute;
  left: 0;
  right: 0;
  height: 0;
  border-top: 1px dashed var(--color-surface-2);
  pointer-events: none;
}

/* Container of the 7 day columns. Sits inside the plot, leaving a
   1.75rem gutter at the bottom for the day labels (so labels live
   under the plot border, not over the bars). */
.week-chart__bars {
  position: absolute;
  inset: 0 0 0 0;
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}

.week-day {
  position: relative;
  background: transparent;
  border: 0;
  padding: 0 var(--space-xs);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-end;
  cursor: pointer;
  transition: background var(--transition-fast);
}

.week-day:hover { background: rgba(255, 255, 255, 0.04); }

.week-day--today .week-day__label {
  color: var(--color-text);
  font-weight: 600;
}

/* Bar height = the area between the bottom of the plot and the day
   label gutter. column-reverse stacks segments from the bottom (work
   first, break on top) regardless of source order. */
.week-day__bar {
  flex: 1;
  margin-bottom: 1.75rem;
  display: flex;
  flex-direction: column-reverse;
  align-items: stretch;
  justify-content: flex-start;
}

.week-day__seg {
  width: 100%;
  min-height: 1px;
  transition: opacity var(--transition-fast);
}

.week-day__seg--work  { background: var(--tool-color, var(--color-work)); }
.week-day__seg--break { background: var(--color-break); }

.week-day:hover .week-day__seg { opacity: 0.88; }

.week-day__label {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  text-align: center;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  padding-top: var(--space-xs);
  border-top: 1px solid var(--color-surface-2);
  font-variant-numeric: tabular-nums;
}

/* ============ Day view (24-hour timeline) ============ */

.day-view {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.day-view__header {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  flex-wrap: wrap;
}

.day-view__back {
  background: var(--color-surface);
  color: var(--color-text);
  padding: var(--space-xs) var(--space-md);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  transition: background var(--transition-fast);
}

.day-view__back:hover { background: var(--color-surface-2); }

.day-view__titles {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.day-view__title {
  font-size: var(--font-size-lg);
  font-weight: 500;
}

.day-view__sw {
  font-size: var(--font-size-sm);
  color: var(--tool-color, var(--color-accent));
  font-weight: 500;
}

.day-view__empty {
  color: var(--color-text-dim);
  font-size: var(--font-size-sm);
  padding: var(--space-sm) 0;
}

/* Pan/zoom viewport for the day timeline. The native scrollbar is gone
   on purpose — pan is handled by left-click drag (with tanh-damped
   overscroll at both edges) and zoom by the scroll wheel (anchored on
   the cursor) or the +/- buttons below (anchored on the viewport
   center). The inner element's width is set inline to (24 / visible)
   * 100%, and its translateX is updated by the drag/zoom handlers. */
.day-view__viewport {
  overflow: hidden;
  position: relative;
  background: var(--color-surface);
  border-radius: var(--radius-md);
  padding: var(--space-md) 0;
  touch-action: pan-y; /* let the page scroll vertically; we handle X */
}

.day-view__inner {
  position: relative;
  height: 7rem;
  min-width: 100%;
  cursor: grab;
  user-select: none;
  touch-action: none;
  will-change: transform;
}

.day-view__inner--dragging { cursor: grabbing; }

/* Used briefly on pointerup when we need to animate back from an
   over-scrolled position into the clamped bounds. Removed by JS after
   the transition would have completed so subsequent drags feel direct. */
.day-view__inner--snapping {
  transition: transform 0.32s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Zoom controls below the timeline: small circular buttons,
   centered. Intentionally unlabeled — the icons (− / +) carry their
   meaning. */
.day-view__zoom-controls {
  display: flex;
  justify-content: center;
  gap: var(--space-sm);
  margin-top: var(--space-md);
}

.day-view__zoom-btn {
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-text);
  font-size: 1.1rem;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background var(--transition-fast), transform var(--transition-fast);
}

.day-view__zoom-btn:hover { background: var(--color-surface-2); }
.day-view__zoom-btn:active { transform: scale(0.92); }

/* 24 hour markers (plus an end tick at 100%). Each marker has a
   thin vertical gridline and a small label below it. */
.day-view__grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.day-view__hour {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0;
  transform: translateX(-1px);
}

.day-view__hour-line {
  position: absolute;
  top: 0;
  bottom: 1.5rem;
  left: 0;
  border-left: 1px dashed var(--color-surface-2);
}

.day-view__hour-label {
  position: absolute;
  bottom: 0;
  left: 0;
  transform: translateX(-50%);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.day-view__hour--end .day-view__hour-label {
  transform: translateX(-100%);
}

/* Sessions sit on a horizontal track above the hour labels. Each
   session is a small bar positioned by start time, split into work
   and break segments. */
.day-view__track {
  position: absolute;
  top: 1rem;
  bottom: 2rem;
  left: 0;
  right: 0;
}

.day-session {
  position: absolute;
  top: 0;
  bottom: 0;
  background: var(--color-bg);
  border-radius: var(--radius-sm);
  overflow: hidden;
  display: flex;
  min-width: 2px;
}

.day-seg {
  position: absolute;
  top: 0;
  bottom: 0;
  min-width: 1px;
}

.day-seg--work  { background: var(--tool-color, var(--color-work)); }
.day-seg--break { background: var(--color-break); }

/* ============ Responsive ============ */

@media (max-width: 700px) {
  .topbar {
    padding: 0 var(--space-md);
  }
  .layout {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
  }
  .sidebar {
    border-right: none;
    border-bottom: 1px solid var(--color-surface-2);
    max-height: 50vh;
  }
  .main {
    padding: var(--space-md);
  }
  .session, .tl-row {
    grid-template-columns: 1fr auto;
  }
  .session__when {
    grid-column: 1 / -1;
  }
  .tl-row__label {
    grid-column: 1 / -1;
    flex-direction: row;
    gap: var(--space-sm);
  }
  .tl-bar {
    grid-column: 1 / -1;
  }
}

/* ============ Settings page ============ */

/* The sidebar on the Settings page reuses the same .sidebar container
   (background, scroll, border) as the main app's tool list — the
   visual chrome is page-agnostic. Only the inner content (categories
   nav instead of tool panels) is settings-specific. */

.settings-categories {
  display: flex;
  flex-direction: column;
  padding: var(--space-md) 0;
}

.settings-category {
  display: block;
  width: 100%;
  padding: var(--space-md) var(--space-lg);
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-base);
  text-align: left;
  border: none;
  border-left: 3px solid transparent;
  transition: background var(--transition-fast), color var(--transition-fast),
              border-color var(--transition-fast);
}

.settings-category:hover {
  background: var(--color-surface-2);
  color: var(--color-text);
}

.settings-category--active {
  background: var(--color-surface-2);
  color: var(--color-text);
  border-left-color: var(--color-accent);
  font-weight: 500;
}

.settings-main {
  /* Slightly tighter than the main app's history pane — settings is
     mostly forms and read-only info, doesn't need the same breathing
     room as a timeline chart. */
  max-width: 48rem;
}

.settings-panel[hidden] { display: none; }

.settings-panel__title {
  font-size: var(--font-size-xl);
  font-weight: 500;
  margin-bottom: var(--space-md);
}

.settings-panel__placeholder {
  color: var(--color-text-dim);
  font-size: var(--font-size-sm);
  padding: var(--space-md);
  background: var(--color-surface);
  border-radius: var(--radius-md);
  border: 1px dashed var(--color-surface-2);
}

/* Anonymous-state callout inside a settings panel (e.g. Account panel
   when no one is signed in). Visually distinct from a regular panel
   body — a dashed muted block telling the user where to go. */
.settings-empty {
  padding: var(--space-md);
  background: var(--color-surface);
  border: 1px dashed var(--color-surface-2);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  line-height: 1.5;
}

.settings-empty p { margin-bottom: var(--space-xs); }
.settings-empty p:last-child { margin-bottom: 0; }

/* Section grouping inside a panel. Section title sits above with an
   underline; hint text below explains its purpose. */
.settings-section {
  margin-bottom: var(--space-2xl);
}

.settings-section:last-child { margin-bottom: 0; }

.settings-section__title {
  font-size: var(--font-size-base);
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: var(--space-md);
  padding-bottom: var(--space-xs);
  border-bottom: 1px solid var(--color-surface-2);
}

.settings-section__title--danger { color: var(--color-danger); }

.settings-section__hint {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  margin-bottom: var(--space-md);
  line-height: 1.5;
}

/* Label / value pairs for read-only account fields (email, user id,
   member-since). Label is small-caps muted; value is regular text. */
.settings-field {
  margin-bottom: var(--space-md);
}

.settings-field:last-child { margin-bottom: 0; }

.settings-field__label {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 2px;
}

.settings-field__value {
  font-size: var(--font-size-base);
  color: var(--color-text);
  word-break: break-all;
}

/* Inline word after a numeric/time input, e.g. "minutes before". */
.settings-field__suffix {
  display: inline-block;
  margin-left: var(--space-xs);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* Profile picture section in the Account panel: a square preview on
   the left, action buttons stacked on the right. */
.settings-avatar {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin-top: var(--space-sm);
}

.settings-avatar__preview {
  width: 4.5rem;
  height: 4.5rem;
  flex: 0 0 auto;
  border-radius: 50%;
  overflow: hidden;
  background: var(--color-accent);
  color: var(--color-text);
  display: flex;
  align-items: center;
  justify-content: center;
}

.settings-avatar__preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.settings-avatar__initials {
  font-size: 1.75rem;
  font-weight: 600;
  text-transform: uppercase;
  user-select: none;
}

.settings-avatar__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

/* Standout treatment for the "this is irreversible" line above the
   delete-account confirmation form. */
.settings-section__hint--danger {
  color: var(--color-danger);
}

/* Row of buttons under a form (e.g., Delete / Cancel on the delete-
   account confirmation). */
.settings-form__actions {
  display: flex;
  gap: var(--space-sm);
  margin-top: var(--space-sm);
}

.settings-field__value--mono {
  font-family: var(--font-display);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* In-panel forms (change-password, future import-file form, etc.).
   Capped width so inputs don't stretch absurdly wide on big screens. */
.settings-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  max-width: 24rem;
}

.settings-form__field {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.settings-form__field input {
  padding: var(--space-sm) var(--space-md);
  background: var(--color-bg);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--font-size-base);
}

.settings-form__field input:focus {
  outline: none;
  border-color: var(--color-accent);
}

.settings-form__message {
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-sm);
  line-height: 1.4;
}

.settings-form__message[hidden] { display: none; }

.settings-form__message--info {
  background: rgba(78, 205, 196, 0.12);
  color: var(--color-success);
}

.settings-form__message--error {
  background: rgba(255, 107, 107, 0.12);
  color: var(--color-danger);
}

.settings-form button[type="submit"] {
  align-self: flex-start;
  margin-top: var(--space-xs);
}

/* Single-control rows in a panel (time picker, select). Used in the
   Behavior tab — narrower than the change-password form fields,
   appears alone in a settings-field block. */
.settings-form__inline-input {
  padding: var(--space-sm) var(--space-md);
  background: var(--color-bg);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  min-width: 12rem;
}

.settings-form__inline-input:focus {
  outline: none;
  border-color: var(--color-accent);
}

/* ============ Task Organizer page ============ */

/* Wider sidebar (1/3 vs Time Organizer's 1/5). On wide screens the
   columns are 1fr/2fr (exact 1:2). On narrow screens the sidebar
   clamps to a min so the task list stays usable. The mobile media
   query at the bottom of this file collapses both layouts the same
   way. */
.layout--tasks {
  grid-template-columns: minmax(320px, 1fr) 2fr;
}

/* Add Task button. Visually mirrors .add-tool from index.html — same
   chrome, same dimensions, different label. */

.add-task {
  padding: var(--space-md) var(--space-lg);
  border-bottom: 1px solid var(--color-surface-2);
}

.add-task__btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  background: var(--color-surface-2);
  color: var(--color-text);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  font-weight: 500;
  transition: background var(--transition-fast);
}

.add-task__btn:hover { background: #3a3a66; }

.add-task__plus {
  font-size: 1.2em;
  line-height: 1;
  color: var(--color-accent);
}

/* Where the task list will live once we add task creation. Empty for
   now — only the Add Task button is rendered. */
.tasks-list {
  display: flex;
  flex-direction: column;
}

/* The Tasks main pane holds the section header + the active view
   (Calendar or Bulletin Board). Disable the default main-area
   vertical scrolling so the active view sizes to the available
   space rather than scrolling its own rows. */
.tasks-main {
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Section header — same shape as Time Organizer's history__header
   (title on the left, view toggle on the right). Reuses the existing
   .view-toggle / .view-toggle__btn styles. */
.tasks-main__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-md);
  flex-wrap: wrap;
  margin-bottom: var(--space-md);
  flex-shrink: 0;
}

.tasks-main__title {
  font-size: var(--font-size-xl);
  font-weight: 500;
}

.tasks-main__actions {
  display: flex;
  align-items: center;
  gap: var(--space-md);
}

/* The active view fills the remaining height; the inactive one is
   hidden. Both share these size rules. */
.tasks-view {
  flex: 1;
  min-height: 0;
}

.tasks-view[hidden] { display: none; }

.month-calendar {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 24rem;
}

.month-calendar__header {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-md);
  margin-bottom: var(--space-md);
}

.month-calendar__title {
  font-size: var(--font-size-lg);
  font-weight: 500;
  min-width: 12rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.month-calendar__nav {
  width: 2.25rem;
  height: 2.25rem;
  background: var(--color-surface);
  color: var(--color-text);
  border-radius: 50%;
  font-size: 1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background var(--transition-fast);
}

.month-calendar__nav:hover { background: var(--color-surface-2); }

.month-calendar__dow {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-align: center;
  padding: var(--space-xs) 0;
  border-bottom: 1px solid var(--color-surface-2);
  margin-bottom: 2px;
}

/* The grid is always 6 rows × 7 cols (42 cells) so adjacent months
   share layout — clicking ←/→ doesn't make the grid grow or shrink. */
.month-calendar__grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  grid-template-rows: repeat(6, 1fr);
  gap: 2px;
  flex: 1;
  background: var(--color-surface-2);
  border-radius: var(--radius-md);
  padding: 2px;
  overflow: hidden;
}

/* Calendar day cell — a column with a non-scrolling header (day
   number) and a scrollable body (entries). The body's overflow lets
   long task/event lists scroll WITHIN the cell so the cell itself
   doesn't grow, and the header stays pinned by virtue of being in a
   separate flex child above the scroll area. */
.month-day {
  background: var(--color-surface);
  border: none;
  color: var(--color-text);
  font-family: var(--font-body);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  cursor: pointer;
  transition: background var(--transition-fast);
  border-radius: var(--radius-sm);
  position: relative;
  min-height: 3rem;
  min-width: 0; /* let entries shrink rather than blow out the grid track */
}

.month-day:hover { background: var(--color-surface-2); }

.month-day:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}

.month-day--other          { background: var(--color-bg); }
.month-day--other .month-day__number { color: var(--color-text-dim); }
.month-day--today          { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.month-day--today .month-day__number { color: var(--color-accent); font-weight: 600; }

.month-day__header {
  padding: var(--space-xs) var(--space-sm);
  flex: 0 0 auto;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-xs);
}

.month-day__number {
  font-size: var(--font-size-sm);
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}

/* Plain-text "N Tasks" link beside the day number — deliberately not
   a pill and not colored, so the calendar reads as events-first.
   Clicking it jumps to the Bulletin Board view. */
.month-day__task-count {
  background: transparent;
  border: none;
  padding: 0;
  font-size: 0.7rem;
  color: var(--color-text-muted);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--transition-fast);
}

.month-day__task-count:hover {
  color: var(--color-text);
  text-decoration: underline;
}

.month-day__entries {
  flex: 1 1 auto;
  min-height: 0;        /* allow this flex child to shrink so overflow kicks in */
  overflow-y: auto;
  padding: 0 var(--space-xs) var(--space-xs);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Subtle scrollbar to match the rest of the app's dark surface. */
.month-day__entries::-webkit-scrollbar         { width: 6px; }
.month-day__entries::-webkit-scrollbar-thumb   { background: var(--color-surface-2); border-radius: 3px; }

/* Event pill — calendar entries are events-only. Buttons so they're
   keyboard-reachable; clicking bubbles up to the grid's delegated
   handler which reads data-event-id. Vertical padding is deliberately
   generous (a comfortable click target) — days that overflow scroll
   inside .month-day__entries. */
.month-day__entry {
  display: flex;
  align-items: baseline;
  gap: var(--space-xs);
  padding: 5px var(--space-xs);
  background: var(--color-surface-2);
  color: var(--color-text);
  border-radius: var(--radius-sm);
  font-size: 0.75rem;
  line-height: 1.2;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
  transition: background var(--transition-fast);
}

.month-day__entry:hover { background: var(--color-bg); }

.month-day__entry-time {
  flex: 0 0 auto;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
  font-size: 0.7rem;
}

.month-day__entry-title {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Per-event accent — a thin colored left border. The pill sets
   --event-color inline from the event's saved color (or the default
   green when unset). */
.month-day__entry--event {
  border-left: 3px solid var(--event-color, #4ade80);
}

/* ============ Bulletin Board view ============ */

/* Three sections in a 1fr/2fr split:
       broad — full width, top 1/3
       daily — bottom-left, half of bottom 2/3
       weekly — bottom-right, other half of bottom 2/3
   Each section has a colored "tab" header and a content body. The
   section color is exposed via --section-color (vivid, for the
   title) and --section-color-tab (translucent, for the header
   background). */

.bulletin-board {
  display: grid;
  grid-template-rows: 1fr 2fr;
  grid-template-columns: 1fr 1fr;
  grid-template-areas:
    "broad broad"
    "daily weekly";
  gap: var(--space-md);
  height: 100%;
}

.bulletin-board__section {
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border-radius: var(--radius-md);
  overflow: hidden;
  min-height: 8rem;
}

.bulletin-board__section--broad {
  grid-area: broad;
  --section-color: #a67c52;                          /* brown */
  --section-color-tab: rgba(166, 124, 82, 0.18);
}

.bulletin-board__section--daily {
  grid-area: daily;
  --section-color: #6c8eff;                          /* blue */
  --section-color-tab: rgba(108, 142, 255, 0.18);
}

.bulletin-board__section--weekly {
  grid-area: weekly;
  --section-color: #4ade80;                          /* green */
  --section-color-tab: rgba(74, 222, 128, 0.16);
}

/* The "tab" — a softly tinted strip at the top of each section. The
   title text inside is rendered in the saturated section color for
   contrast (per the user spec: 'transparent tab + sharper title'). */
.bulletin-board__tab {
  padding: var(--space-sm) var(--space-md);
  background: var(--section-color-tab);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
}

.bulletin-board__title {
  color: var(--section-color);
  font-weight: 600;
  font-size: var(--font-size-base);
  margin: 0;
}

.bulletin-board__countdown {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-variant-numeric: tabular-nums;
}

.bulletin-board__body {
  flex: 1;
  padding: var(--space-md);
  overflow-y: auto;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  line-height: 1.5;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

/* ============ Add Task button + inline form ============ */
/* The Add Task button sits at the top of the sidebar (already styled
   via .add-task / .add-task__btn). When opened, an inline form
   appears below it. */

.add-task__form {
  margin-top: var(--space-md);
  padding: var(--space-md);
  background: var(--color-bg);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.add-task__form[hidden] { display: none; }

.add-task__field {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Without this explicit override, the [hidden] attribute is defeated
   by the .add-task__field { display: flex } rule above (same
   specificity, later wins) — meaning toggles in setFormMode(...)
   would visually do nothing. Mirrors the same override on
   .add-task__deadline[hidden] below. */
.add-task__field[hidden] { display: none; }

.add-task__field--inline {
  flex-direction: row;
  align-items: center;
  gap: var(--space-xs);
}

.add-task__label {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  letter-spacing: 0.02em;
}

.add-task__form input[type="text"],
.add-task__form textarea,
.add-task__form select,
.add-task__form input[type="date"],
.add-task__form input[type="time"] {
  padding: var(--space-xs) var(--space-sm);
  background: var(--color-surface);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  width: 100%;
}

.add-task__form input:focus,
.add-task__form textarea:focus,
.add-task__form select:focus {
  outline: none;
  border-color: var(--color-accent);
}

.add-task__form textarea {
  resize: vertical;
  min-height: 2.5rem;
}

.add-task__deadline {
  display: flex;
  gap: var(--space-xs);
}

.add-task__deadline[hidden] { display: none; }

.add-task__deadline input { flex: 1; }

/* Event color swatch grid in the inline form's event modes. Mirrors
   the Time Organizer recolor swatches (.feature__color) so the two
   recolor surfaces feel consistent. */
.add-task__color-grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}

.add-task__color {
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform var(--transition-fast), border-color var(--transition-fast);
}

.add-task__color:hover { transform: scale(1.12); }
.add-task__color--selected { border-color: var(--color-text); }
.add-task__color:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.add-task__form-message {
  font-size: var(--font-size-sm);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
}

.add-task__form-message[hidden] { display: none; }

.add-task__form-message--error {
  background: rgba(255, 107, 107, 0.12);
  color: var(--color-danger);
}

.add-task__form-message--info {
  background: rgba(78, 205, 196, 0.12);
  color: var(--color-success);
}

.add-task__actions {
  display: flex;
  gap: var(--space-xs);
  margin-top: var(--space-xs);
}

/* ============ Task categories (sidebar) ============ */

.task-categories {
  display: flex;
  flex-direction: column;
}

/* Each top-level category is a <details>. Removing the default
   marker so we can render our own chevron. */
.task-category {
  border-bottom: 1px solid var(--color-surface-2);
}

.task-category > summary,
.task-subcategory > summary {
  list-style: none;
  cursor: pointer;
}
.task-category > summary::-webkit-details-marker,
.task-subcategory > summary::-webkit-details-marker {
  display: none;
}

.task-category__summary {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md) var(--space-lg);
  font-size: var(--font-size-base);
  font-weight: 500;
  color: var(--color-text);
  transition: background var(--transition-fast);
}

.task-category__summary:hover { background: var(--color-surface-2); }

.task-category__chevron,
.task-subcategory__chevron {
  display: inline-block;
  color: var(--color-text-muted);
  font-size: 0.8em;
  transition: transform var(--transition-base);
}

.task-category[open] > summary .task-category__chevron,
.task-subcategory[open] > summary .task-subcategory__chevron {
  transform: rotate(180deg);
}

.task-category__title { flex: 1; min-width: 0; }

.task-category__countdown {
  font-family: var(--font-display);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.task-category__list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0 var(--space-md) var(--space-md);
}

.task-list__empty {
  font-size: var(--font-size-sm);
  color: var(--color-text-dim);
  padding: var(--space-sm) var(--space-sm);
  text-align: center;
  font-style: italic;
}

/* The Bulletin Board sidebar category nests three sub-categories.
   They share the section colors from --section-color (defined on the
   bulletin board view's section classes); here we just reapply via
   modifier classes so the sidebar's title gets a matching tint. */

.task-category--bulletin > .task-category__summary {
  /* slightly bolder treatment to distinguish it from non-nested
     categories — has a known "this expands into more things" shape */
}

.task-subcategory {
  padding-left: var(--space-md);
}

.task-subcategory__summary {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  font-size: var(--font-size-sm);
  font-weight: 500;
  transition: background var(--transition-fast);
}

.task-subcategory__summary:hover { background: var(--color-surface-2); }

.task-subcategory__title { flex: 1; min-width: 0; }

.task-subcategory--broad  .task-subcategory__title { color: #a67c52; }
.task-subcategory--daily  .task-subcategory__title { color: #6c8eff; }
.task-subcategory--weekly .task-subcategory__title { color: #4ade80; }

.task-subcategory__countdown {
  font-family: var(--font-display);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

/* ============ Task cards ============ */
/* Render in the sidebar lists and in the bulletin board view bodies. */

.task-card {
  display: flex;
  align-items: stretch;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  background: var(--color-surface);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-sm);
  transition: background var(--transition-fast);
}

.task-card:hover { background: var(--color-surface-2); }

.task-card__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 2px 0;
}

.task-card__title {
  font-size: var(--font-size-sm);
  color: var(--color-text);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.task-card__meta {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Empty-square "checkbox" — sits on the left of each unfinished
   task card. Clicking it marks the task finished, which moves it
   to the Finished category where the card itself becomes the
   "checked" indicator (green box). No content inside; the box is
   the visual. */
.task-card__check {
  width: 1rem;
  height: 1rem;
  align-self: center;
  flex-shrink: 0;
  padding: 0;
  background: transparent;
  border: 2px solid var(--color-text-muted);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 0;       /* hides any whitespace text node inside */
  transition: border-color var(--transition-fast),
              background var(--transition-fast);
}

.task-card__check:hover {
  border-color: var(--color-success);
  background: rgba(78, 205, 196, 0.12);
}

/* Pencil edit button — sits on the right of each task card. Click
   opens the add-task form in edit mode (pre-populated with this
   task's values; deletion lives inside that form, not as a separate
   × on the card). */
.task-card__edit {
  width: 1.5rem;
  height: 1.5rem;
  align-self: center;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--color-text-muted);
  border-radius: 50%;
  font-size: 0.9rem;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.task-card__edit:hover {
  background: var(--color-surface-2);
  color: var(--color-text);
}

/* Finished tasks get a green box treatment — per spec ("green box"). */
.task-card--finished {
  background: rgba(78, 205, 196, 0.08);
  border-color: rgba(78, 205, 196, 0.4);
}
.task-card--finished:hover {
  background: rgba(78, 205, 196, 0.12);
}
.task-card--finished .task-card__title {
  text-decoration: line-through;
  color: var(--color-text-muted);
}

/* Expired tasks get a yellow box, displayed above un-deadlined ones
   in the To Do category (sorting handled in Tasks.getToDo). */
.task-card--expired {
  background: rgba(255, 209, 102, 0.10);
  border-color: rgba(255, 209, 102, 0.5);
}
.task-card--expired:hover {
  background: rgba(255, 209, 102, 0.15);
}
.task-card--expired .task-card__meta {
  color: var(--color-warning);
}

/* Tasks the user can drag. Finished tasks aren't draggable (no
   business moving them around) and don't get the grab cursor. */
.task-card[draggable="true"] { cursor: grab; }
.task-card[draggable="true"]:active { cursor: grabbing; }

.task-card--dragging { opacity: 0.4; }

/* Drop-target highlight on a bulletin board section (main view). */
.bulletin-board__section--drop-target {
  outline: 2px dashed var(--color-accent);
  outline-offset: -2px;
}

/* Drop-target highlight on a sidebar bulletin sub-category. The tint
   sits on the summary row only so the chevron stays the focal point. */
.task-subcategory--drop-target > summary {
  background: rgba(108, 142, 255, 0.18);
}

/* Curved-arrow overlay shown over the entire sidebar when a board
   task is being dragged out toward the shoulder. The accent-color
   border + dashed pattern signals "drop zone"; pointer-events:none
   so the underlying dragover handler keeps firing. */
.shoulder-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(108, 142, 255, 0.12);
  border: 2px dashed var(--color-accent);
  border-radius: var(--radius-md);
  pointer-events: none;
  z-index: 20;
}

.shoulder-overlay[hidden] { display: none; }

.shoulder-overlay__inner {
  text-align: center;
  color: var(--color-accent);
  padding: var(--space-md);
}

.shoulder-overlay__arrow {
  display: block;
  margin: 0 auto var(--space-sm);
}

.shoulder-overlay__label {
  display: block;
  font-size: var(--font-size-sm);
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* ===========================================================
   Notifications — bell badge + dropdown panel
   ===========================================================
   UINotifications wraps the topbar bell in a .notif-menu container
   at init (no per-page HTML changes). The badge sits inside the bell
   button (top-left); the panel is a sibling, positioned below the
   bell, mirroring the profile-menu dropdown's layout idioms. */

.notif-menu {
  position: relative;
  display: flex;
  align-items: center;
}

/* Red "!" badge — shown while unreadCount > 0. Pulses subtly to draw
   attention without being noisy; pause on hover to ease focus when
   the user is about to click. */
.notif-menu__badge {
  position: absolute;
  top: -2px;
  left: -2px;
  min-width: 14px;
  height: 14px;
  padding: 0 3px;
  background: var(--color-danger);
  color: var(--color-text);
  border-radius: 50%;
  font-size: 10px;
  font-weight: 700;
  line-height: 14px;
  text-align: center;
  pointer-events: none;
  box-shadow: 0 0 0 2px var(--color-bg);
  animation: notif-pulse 1.6s ease-in-out infinite;
}

.notif-menu__badge[hidden] { display: none; }

.topbar__bell:hover .notif-menu__badge { animation-play-state: paused; }

@keyframes notif-pulse {
  0%, 100% { transform: scale(1);    opacity: 1; }
  50%      { transform: scale(1.18); opacity: 0.9; }
}

/* Dropdown panel — same surface/border treatment as the profile
   dropdown so the two feel like siblings. Wider since notification
   text wraps; capped by max-height with scroll. */
.notif-menu__panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  width: 22rem;
  max-height: 24rem;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: 1px solid var(--color-surface-2);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
  z-index: 20;
  overflow: hidden;
}

.notif-menu__panel[hidden] { display: none; }

.notif-menu__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--color-surface-2);
}

.notif-menu__title {
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--color-text);
}

.notif-menu__clear {
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  padding: 2px var(--space-xs);
  border-radius: var(--radius-sm);
  transition: color var(--transition-fast), background var(--transition-fast);
}

.notif-menu__clear:hover {
  color: var(--color-text);
  background: var(--color-surface-2);
}

/* Inline "Enable desktop notifications" call-to-action. Only visible
   while Notification.permission === 'default'. */
.notif-menu__enable {
  margin: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  background: var(--color-accent);
  color: var(--color-text);
  font-size: var(--font-size-sm);
  font-weight: 500;
  border-radius: var(--radius-sm);
  transition: background var(--transition-fast);
}

.notif-menu__enable:hover { background: var(--color-accent-hover); }
.notif-menu__enable[hidden] { display: none; }

.notif-menu__list {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-xs);
}

.notif-menu__list[hidden] { display: none; }

.notif-menu__empty {
  padding: var(--space-md);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  text-align: center;
}

.notif-menu__empty[hidden] { display: none; }

.notif-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-sm);
  border-radius: var(--radius-sm);
  background: transparent;
  transition: background var(--transition-fast);
}

.notif-item + .notif-item {
  margin-top: 2px;
  border-top: 1px solid var(--color-surface-2);
}

.notif-item:hover { background: var(--color-surface-2); }

.notif-item__icon {
  flex: 0 0 auto;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: var(--color-danger);
  color: var(--color-text);
  font-weight: 700;
  font-size: 0.875rem;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 2px;
}

.notif-item__body {
  flex: 1 1 auto;
  min-width: 0;
}

.notif-item__message {
  font-size: var(--font-size-sm);
  color: var(--color-text);
  line-height: 1.35;
  word-wrap: break-word;
}

.notif-item__time {
  margin-top: 2px;
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

/* ===========================================================
   Mobile week calendar (portrait / narrow — <=700px)
   ===========================================================
   On a phone the 7-column month grid is unusable, so the Task
   Organizer's calendar view swaps to a swipe-able week view:
   a month-name bar (opens a mini-month dropdown), a week
   scroller strip, seven fixed day cells Sun-Sat, and an event
   area that hosts the relocated add/edit form. Built + driven
   by ui-tasks.js. Hidden entirely on desktop. */

.week-calendar { display: none; }

/* The collapsible-bottom-sheet toggle handle. Hidden on desktop;
   shown on mobile inside the calendar event area and the sidebar. */
.sheet-toggle { display: none; }

@media (max-width: 700px) {
  /* ----- Tasks page mobile shell ----- */
  .layout--tasks { grid-template-columns: 1fr; }

  /* Compact the view-toggle header down to just the toggle. */
  .tasks-main { padding: 0; }
  .tasks-main__header {
    margin-bottom: 0;
    padding: var(--space-xs) var(--space-sm);
    border-bottom: 1px solid var(--color-surface-2);
  }
  .tasks-main__title { display: none; }

  /* Desktop month grid off; the week calendar takes over. */
  .month-calendar__header,
  .month-calendar__dow,
  .month-calendar__grid { display: none; }
  .month-calendar { min-height: 0; }
  .week-calendar {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    position: relative;
  }

  /* ----- Calendar view: sidebar gone, main fills ----- */
  .layout--tasks[data-active-view="calendar"] { grid-template-rows: 1fr; }
  .layout--tasks[data-active-view="calendar"] .sidebar { display: none; }
  .layout--tasks[data-active-view="calendar"] .main    { grid-row: 1; }

  /* ----- Bulletin view: board on top, sidebar as bottom sheet -----
     The sidebar is the desktop "left shoulder" (Add Task + form +
     category lists); on mobile it docks under the board as the
     1/4-height (toggle → 3/4) sheet. */
  .layout--tasks[data-active-view="bulletin"] { grid-template-rows: 3fr 1fr; }
  .layout--tasks[data-active-view="bulletin"][data-sheet="expanded"] {
    grid-template-rows: 1fr 3fr;
  }
  .layout--tasks[data-active-view="bulletin"] .main {
    grid-row: 1;
    min-height: 0;
  }
  .layout--tasks[data-active-view="bulletin"] .sidebar {
    grid-row: 2;
    display: flex;
    flex-direction: column;
    min-height: 0;
    max-height: none;
    overflow-y: auto;
    border: none;
    border-top: 2px solid var(--color-surface-2);
  }

  /* Smaller Daily / Weekly row so the board reads board-first. */
  .bulletin-board { grid-template-rows: 1.4fr 1fr; }

  /* The sheet toggle handle is mobile-only. */
  .sheet-toggle { display: flex; }
}

/* The .week-calendar__* rules below live outside the media query —
   harmless on desktop since .week-calendar is display:none there. */

/* --- Month-name bar --- */
.week-calendar__monthbar {
  flex: 0 0 auto;
  position: relative; /* anchors the mini-month dropdown */
  border-bottom: 1px solid var(--color-surface-2);
}

.week-calendar__month-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  width: 100%;
  padding: var(--space-sm) var(--space-md);
  background: transparent;
  color: var(--color-text);
  font-size: var(--font-size-base);
  font-weight: 500;
}

.week-calendar__caret {
  color: var(--color-text-muted);
  font-size: 0.7rem;
  transition: transform var(--transition-fast);
}

.week-calendar__month-toggle[aria-expanded="true"] .week-calendar__caret {
  transform: rotate(180deg);
}

/* --- Mini-month dropdown --- */
.week-calendar__monthdrop {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 30;
  background: var(--color-surface);
  border: 1px solid var(--color-surface-2);
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.4);
  padding: var(--space-sm);
}

.week-calendar__monthdrop[hidden] { display: none; }

.week-calendar__minihead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-xs);
}

.week-calendar__minihead span {
  font-size: var(--font-size-sm);
  font-weight: 600;
}

.week-calendar__mininav {
  width: 2rem;
  height: 2rem;
  background: transparent;
  color: var(--color-text);
  border-radius: var(--radius-sm);
  font-size: 1.1rem;
}

.week-calendar__mininav:hover { background: var(--color-surface-2); }

.week-calendar__mini-dow {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  font-size: 0.65rem;
  color: var(--color-text-muted);
  text-align: center;
  text-transform: uppercase;
  margin-bottom: 2px;
}

.week-calendar__mini-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
}

.mini-day {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 2px;
  min-height: 2.5rem;
  padding: 2px 0 4px;
  background: transparent;
  color: var(--color-text);
  border-radius: var(--radius-sm);
}

.mini-day:hover { background: var(--color-surface-2); }
.mini-day--other { color: var(--color-text-dim); }
.mini-day--today {
  outline: 1px solid var(--color-accent);
  outline-offset: -1px;
}

.mini-day__num {
  font-size: var(--font-size-sm);
  font-variant-numeric: tabular-nums;
}

/* Event-presence dots above the day number. Up to 4; a 5th+ shows
   a trailing "+" (rendered by ui-tasks.js). */
.mini-day__dots {
  display: flex;
  align-items: center;
  gap: 2px;
  min-height: 5px;
}

.mini-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--color-accent);
}

.mini-plus {
  font-size: 0.6rem;
  line-height: 1;
  color: var(--color-accent);
}

/* --- Week scroller --- */
/* Horizontal scroll-snap strip; each chip is one full-width week.
   Swiping moves exactly one week (mandatory snap). Deliberately
   distinct from the day columns below — accent-tinted band, bolder
   label — so it reads as the navigation control. */
.week-calendar__scroller {
  flex: 0 0 auto;
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  background: var(--color-surface-2);
  border-bottom: 2px solid var(--color-accent);
}

.week-calendar__scroller::-webkit-scrollbar { display: none; }

.week-chip {
  flex: 0 0 100%;
  scroll-snap-align: start;
  text-align: center;
  padding: var(--space-sm) 0;
  font-size: var(--font-size-base);
  font-weight: 600;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}

/* --- Week grid: 8 day cells, two columns of four (Sun→Sun) ----- */
.week-calendar__week {
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: repeat(4, 1fr);
  grid-auto-flow: column;
  gap: 1px;
  background: var(--color-surface-2); /* shows through the gaps */
}

.week-day {
  min-height: 0;
  display: flex;
  align-items: stretch;
  gap: var(--space-xs);
  padding: 2px var(--space-xs);
  background: var(--color-surface);
  cursor: pointer;
  overflow: hidden;
}

.week-day:hover { background: var(--color-surface-2); }

/* Date block: tiny weekday initial above the day number. */
.week-day__date {
  flex: 0 0 2.25rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  line-height: 1.05;
}

.week-day__dow {
  font-size: 0.6rem;
  text-transform: uppercase;
  color: var(--color-text-muted);
  letter-spacing: 0.04em;
}

.week-day__num {
  font-size: 1.05rem;
  font-variant-numeric: tabular-nums;
}

.week-day--today .week-day__dow,
.week-day--today .week-day__num { color: var(--color-accent); }

/* The cell body finger-scrolls when its events overflow. */
.week-day__body {
  flex: 1 1 auto;
  min-width: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 2px 0;
}

.week-day__events {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Event pills are reused from the month grid (.month-day__entry);
   tighten the padding for the week cells. */
.week-day__events .month-day__entry {
  padding: 3px var(--space-xs);
}

/* --- Collapsible bottom sheet ----------------------------------
   Both the calendar event area and (in bulletin view) the sidebar
   are "bottom sheets": 1/4 of the screen by default, toggled to
   3/4 by the .sheet-toggle handle. The toggle flips data-sheet on
   .layout--tasks; the size rules key off it. */

.sheet-toggle {
  position: sticky;
  top: 0;
  z-index: 2;
  width: 100%;
  align-items: center;
  justify-content: center;
  padding: 5px;
  background: var(--color-surface-2);
  color: var(--color-text-muted);
  border-bottom: 1px solid var(--color-surface-2);
}

.sheet-toggle__chevron {
  font-size: 0.75rem;
  transition: transform var(--transition-fast);
}

.layout--tasks[data-sheet="expanded"] .sheet-toggle__chevron {
  transform: rotate(180deg);
}

/* Calendar bottom sheet: the week grid vs the event area split. */
.layout--tasks[data-active-view="calendar"] .week-calendar__week       { flex: 3 1 0; }
.layout--tasks[data-active-view="calendar"] .week-calendar__event-area { flex: 1 1 0; }
.layout--tasks[data-active-view="calendar"][data-sheet="expanded"] .week-calendar__week       { flex: 1 1 0; }
.layout--tasks[data-active-view="calendar"][data-sheet="expanded"] .week-calendar__event-area { flex: 3 1 0; }

/* --- Event area: hosts the relocated add/edit form --- */
.week-calendar__event-area {
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  border-top: 2px solid var(--color-surface-2);
}

.week-calendar__hint {
  color: var(--color-text-dim);
  font-size: var(--font-size-sm);
  text-align: center;
  padding: var(--space-lg) var(--space-md);
}

.week-calendar__hint[hidden] { display: none; }

/* The relocated form fills the event area rather than reading as a
   floating panel — it IS the panel here. */
.week-calendar__event-area .add-task__form {
  margin-top: 0;
  border: none;
  background: transparent;
  padding: var(--space-sm);
}
