@font-face {
  font-family: 'JetBrains Mono';
  src: url('/assets/fonts/jetbrains-mono-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('/assets/fonts/jetbrains-mono-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('/assets/fonts/jetbrains-mono-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Aileron';
  src: url('/assets/fonts/Aileron-Black.otf') format('opentype');
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Aileron';
  src: url('/assets/fonts/Aileron-UltraLight.otf') format('opentype');
  font-weight: 200;
  font-style: normal;
  font-display: swap;
}

:root {
  --canvas: #fdfcfc;
  --canvas-dark: #f0efef;
  --ink: #201d1d;
  --accent: #007aff;
  --border: #201d1d;
  --radius: 4px;
}

* {
  box-sizing: border-box;
}

html {
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* legacy Edge */
}
html::-webkit-scrollbar {
  display: none; /* Chrome, Safari, Chromium Edge */
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  /* This is an app UI, not text content -- selection highlighting is
     mostly an annoyance here, and double-clicking a clip row to delete
     it would otherwise select its text on every click. */
  -webkit-user-select: none;
  user-select: none;
}

h1,
h2,
h3 {
  font-family: 'Aileron', 'JetBrains Mono', ui-monospace, monospace;
  font-weight: 900;
  letter-spacing: -0.01em;
  margin: 0 0 0.5em;
}

.hairline {
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.brackets::before {
  content: '[ ';
}
.brackets::after {
  content: ' ]';
}

/* Two-column app shell: a sticky side menu (logo + session controls) and
   a scrolling main column (calendar + small footer). */
.app-shell {
  display: flex;
  align-items: stretch;
  min-height: 100vh;
}

.side-menu {
  position: sticky;
  top: 0;
  height: 100vh;
  width: 280px;
  flex-shrink: 0;
  overflow-y: auto;
  border-right: 1px solid var(--border);
  background: var(--ink);
  color: var(--canvas);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.side-menu-header h1 {
  margin: 0;
}

.side-menu-status {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  margin: 4px 0 0;
  opacity: 0.6;
}

.side-menu-status[data-calibrated='true'] {
  color: var(--accent);
  opacity: 1;
}

.side-menu-help {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.75rem;
  line-height: 1.5;
  margin: 12px 0 0;
  opacity: 0.65;
}

/* Buttons keep their own explicit ink-on-canvas contrast, so they read
   fine as-is against the dark sidebar. Everything else (calibration
   copy, borders, the idle rec-dot) needs an explicit light override --
   without it they inherit dark ink-on-ink and disappear. */
.side-menu .hairline {
  border-color: var(--canvas);
}


.main-column {
  flex: 1;
  min-width: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 24px;
  gap: 24px;
}

/* The only scrollable region, at every breakpoint -- the side menu is
   sticky and the footer stays pinned below this. */
#calendar-section {
  flex: 1;
  min-height: 0; /* required for a flex child to actually shrink and scroll */
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.site-footer-small {
  margin-top: auto;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  font-size: 0.7rem;
  opacity: 0.7;
}

.site-footer-small a {
  color: var(--ink);
  text-decoration: underline;
}

.site-footer-small a:hover {
  color: var(--accent);
}

.mobile-menu-tab {
  display: none;
}

.side-menu-backdrop {
  display: none;
}

/* Mirrors the sidebar wordmark for mobile, where the side menu (and its
   logo) is tucked away in the slide-out drawer instead of always visible. */
.main-mark {
  display: none;
}

@media (max-width: 768px) {
  .app-shell {
    display: block;
  }

  .main-mark {
    display: block;
    flex-shrink: 0;
    margin: 0 0 12px;
  }

  .side-menu {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: min(85vw, 320px);
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    z-index: 2000;
  }

  .side-menu.open {
    transform: translateX(0);
  }

  .main-column {
    padding-top: 30px; /* clear the fixed mobile tab */
    height: 100vh;
    height: 100dvh; /* ignored by browsers that don't support it, keeping the 100vh fallback above */
  }

  #calendar-section {
    padding-bottom: 16px;
  }

  .site-footer-small {
    flex-shrink: 0;
  }

  .mobile-menu-tab {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
    writing-mode: vertical-rl;
    text-orientation: mixed;
    background: var(--ink);
    color: var(--canvas);
    border: none;
    padding: 16px 8px;
    border-radius: 0 var(--radius) var(--radius) 0;
    z-index: 2100;
    font-family: inherit;
    font-size: 0.9rem;
    letter-spacing: 0.05em;
    cursor: pointer;
  }

  .side-menu-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(32, 29, 29, 0.4);
    z-index: 1900;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
  }

  .side-menu-backdrop.open {
    opacity: 1;
    pointer-events: auto;
  }
}

button {
  font-family: inherit;
  font-size: 1rem;
  background: var(--canvas);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 20px;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

button:hover {
  background: var(--ink);
  color: var(--canvas);
}

button.accent {
  border-color: var(--accent);
  color: var(--accent);
  width: 100%;
}

button.accent:hover {
  background: var(--accent);
  color: var(--canvas);
}

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Wraps the visualizer + record button once calibration is done. Both sit
   clustered near the bottom of the sidebar (see the margin-top: auto
   below), leaving genuine empty space above them. */
.session-section-inner {
  flex: 1;
  min-height: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
}

.visualizer-host {
  flex-shrink: 0;
  width: 100%;
  margin-top: auto;
  margin-bottom: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.visualizer-canvas {
  display: block;
  width: 100%;
  height: 60px;
  border: 1px solid var(--canvas);
  border-radius: var(--radius);
  opacity: 0.9;
}

/* Mixer-style peak meter -- green to red fill drawn on the canvas itself;
   this just gives it a track outline and a fixed slim height. */
.level-meter {
  display: block;
  width: 100%;
  height: 8px;
  border: 1px solid var(--canvas);
  border-radius: var(--radius);
}

.session-widget {
  width: 100%;
  margin-top: auto; /* pin to the bottom of the sidebar, roughly level with the footer */
}

.session-record-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 8px 24px;
  font-size: 1.05rem;
}

.session-record-btn:hover {
  background: var(--canvas);
  color: var(--ink);
}

.rec-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--border);
  flex-shrink: 0;
}

.session-record-btn[data-state='listening'] {
  border-color: var(--accent);
  color: var(--accent);
}
.session-record-btn[data-state='listening'] .rec-dot {
  background: var(--accent);
  animation: rec-pulse 1.4s ease-in-out infinite;
}

/* stage1candidate: onset gate tripped, waiting on stage-2 confirmation --
   distinct from plain listening so it's visible whether detection is
   attempting anything at all. */
.session-record-btn[data-state='stage1candidate'] {
  border-color: #d98c00;
  color: #d98c00;
}
.session-record-btn[data-state='stage1candidate'] .rec-dot {
  background: #d98c00;
  animation: rec-pulse 0.5s ease-in-out infinite;
}

.session-record-btn[data-state='recording'] {
  border-color: #c0392b;
  color: #c0392b;
}
.session-record-btn[data-state='recording'] .rec-dot {
  background: #c0392b;
  animation: rec-pulse 0.8s ease-in-out infinite;
}

@keyframes rec-pulse {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.4;
    transform: scale(1.35);
  }
}
