/* ==========================================================================
   opensoundboard.no — design system (open-base) + the board
   Ultra-minimal: light neutral background, white borderless surfaces, pills,
   near-monochrome. Geist for content, Geist Mono for numbers and micro labels.
   The accent color is reserved for alarm/critical states only.
   ========================================================================== */

@font-face {
  font-family: "Geist";
  src: url("fonts/Geist-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: optional;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Geist";
  src: url("fonts/Geist-var-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: optional;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+1E00-1EFF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Geist Mono";
  src: url("fonts/GeistMono-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: optional;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Geist Mono";
  src: url("fonts/GeistMono-var-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: optional;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+1E00-1EFF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --bg: #f4f4f2;
  --surface: #ffffff;
  --surface-2: #f4f4f2;
  --surface-3: #e9e9e6;
  --text: #171717;
  --text-2: #666666;
  --text-3: #6f6f6f;
  --border: rgba(0, 0, 0, 0.05);
  --border-strong: rgba(0, 0, 0, 0.1);

  --accent: #d92d20;
  --accent-soft: rgba(217, 45, 32, 0.08);

  --ok: #157f3d;

  --inverse-bg: #171717;
  --inverse-text: #fafafa;

  --ring: rgba(0, 0, 0, 0.1);
  --shadow-overlay: 0 4px 12px rgba(0, 0, 0, 0.04), 0 24px 60px rgba(0, 0, 0, 0.1);

  /* the board: pad hover, the playback sweep, slider thumb */
  --pad-hover: #fafaf9;
  --pad-fill: #ebebe8;
  --thumb: #ffffff;

  --font-sans: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236f6f6f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");

  color-scheme: light;
}

:root[data-theme="dark"] {
  --bg: #0e0e0e;
  --surface: #191919;
  --surface-2: #0e0e0e;
  --surface-3: #262626;
  --text: #ededed;
  --text-2: #a3a3a3;
  --text-3: #9a9a9a;
  --border: rgba(255, 255, 255, 0.07);
  --border-strong: rgba(255, 255, 255, 0.14);

  --accent: #f4645a;
  --accent-soft: rgba(244, 100, 90, 0.12);

  --ok: #6ccb8b;

  --inverse-bg: #fafafa;
  --inverse-text: #171717;

  --ring: rgba(255, 255, 255, 0.16);
  --shadow-overlay: 0 4px 12px rgba(0, 0, 0, 0.4), 0 24px 60px rgba(0, 0, 0, 0.55);

  --pad-hover: #1e1e1e;
  --pad-fill: #2b2b2b;
  --thumb: #ededed;

  --chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239a9a9a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");

  color-scheme: dark;
}

/* System dark mode applies unless the user explicitly chose light */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0e0e0e;
    --surface: #191919;
    --surface-2: #0e0e0e;
    --surface-3: #262626;
    --text: #ededed;
    --text-2: #a3a3a3;
    --text-3: #9a9a9a;
    --border: rgba(255, 255, 255, 0.07);
    --border-strong: rgba(255, 255, 255, 0.14);

    --accent: #f4645a;
    --accent-soft: rgba(244, 100, 90, 0.12);

    --ok: #6ccb8b;

    --inverse-bg: #fafafa;
    --inverse-text: #171717;

    --ring: rgba(255, 255, 255, 0.16);
    --shadow-overlay: 0 4px 12px rgba(0, 0, 0, 0.4), 0 24px 60px rgba(0, 0, 0, 0.55);

    --pad-hover: #1e1e1e;
    --pad-fill: #2b2b2b;
    --thumb: #ededed;

    --chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239a9a9a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");

    color-scheme: dark;
  }
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  color: var(--text);
  background-color: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow-x: hidden;
  transition: background-color 0.25s ease, color 0.25s ease;
}

/* Numbers and data: mono with tabular digits so nothing jumps */
.num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.icon {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
  border-radius: 6px;
}

::selection { background: var(--surface-3); }

/* UI chrome must not be text-selectable (iOS long-press etc.).
   Real content/data the user may want to copy stays selectable. */
button, .site-header, .site-footer, .menu, .toast {
  -webkit-user-select: none;
  user-select: none;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.site-header { background: transparent; }

.header-inner {
  max-width: 980px;
  margin: 0 auto;
  padding: 0 20px;
  height: 68px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.brand {
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.01em;
  text-decoration: none;
}

.brand-tld { color: var(--text-3); font-weight: 500; }

.header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.icon-btn {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text);
  background: var(--surface);
  transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}

@media (hover: hover) { .icon-btn:hover { background: var(--surface-3); } }
.icon-btn:active { transform: scale(0.94); }

.icon-btn.open { background: var(--inverse-bg); color: var(--inverse-text); }

/* Toggle buttons (on/off states) invert when active */
.toggle-btn.on { background: var(--inverse-bg); color: var(--inverse-text); }
@media (hover: hover) { .toggle-btn.on:hover { opacity: 0.85; background: var(--inverse-bg); } }

.pill-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 44px;
  padding: 0 22px;
  border-radius: 999px;
  font-size: 14.5px;
  font-weight: 600;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease,
              transform 0.15s ease, opacity 0.15s ease;
}

.pill-btn:active { transform: scale(0.97); }

.pill-btn.primary { background: var(--inverse-bg); color: var(--inverse-text); }
@media (hover: hover) { .pill-btn.primary:hover { opacity: 0.85; } }

.pill-btn.ghost {
  border: 1px solid var(--border-strong);
  color: var(--text);
  background: var(--surface);
}

@media (hover: hover) { .pill-btn.ghost:hover { background: var(--surface-2); } }
.pill-btn[disabled] { opacity: 0.4; pointer-events: none; }

/* --------------------------------------------------------------------------
   Settings menu
   -------------------------------------------------------------------------- */

.settings-wrap { position: relative; }

.menu {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: 296px;
  max-height: min(560px, calc(100dvh - 90px));
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 20px;
  box-shadow: var(--shadow-overlay);
  padding: 20px;
  z-index: 60;
  transform-origin: top right;
  animation: menu-in 0.16s cubic-bezier(0.2, 0.9, 0.3, 1);
}

@keyframes menu-in {
  from { opacity: 0; transform: scale(0.96) translateY(-4px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}

.menu-label {
  display: block;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-3);
  margin-bottom: 10px;
}

/* Options share the row evenly when they fit; locales with long words
   («Pantalla completa», «Бегущая строка») wrap to their own row rather
   than wrapping inside the button. gap applies both ways, so the spacing
   between wrapped rows equals the spacing within a row */
.menu-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.menu-grid .opt-btn { flex: 1 1 auto; white-space: nowrap; }

.menu-select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  font: inherit;
  font-size: 14px;
  color: var(--text);
  background-color: var(--surface-2);
  background-image: var(--chevron);
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 15px;
  border: none;
  border-radius: 12px;
  padding: 11px 44px 11px 14px;
  cursor: pointer;
}

.opt-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 9px 8px;
  border: none;
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 13.5px;
  font-weight: 500;
  text-align: center;
  color: var(--text-2);
  transition: background-color 0.13s ease, color 0.13s ease, transform 0.13s ease;
}

.opt-btn .icon { width: 14px; height: 14px; }

@media (hover: hover) { .opt-btn:hover { background: var(--surface-3); color: var(--text); } }
.opt-btn:active { transform: scale(0.97); }

.opt-btn.active {
  background: var(--inverse-bg);
  color: var(--inverse-text);
  font-weight: 600;
}

.opt-btn.wide { width: 100%; }
.opt-btn.copied { background: var(--ok); color: #fff; }

.menu-divider {
  height: 1px;
  background: var(--border);
  margin: 18px -20px;
}

.menu-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  font-size: 14px;
  line-height: 1.35;
  cursor: pointer;
  user-select: none;
}

.switch {
  appearance: none;
  -webkit-appearance: none;
  flex-shrink: 0;
  width: 40px;
  height: 23px;
  border-radius: 999px;
  background: var(--surface-3);
  position: relative;
  cursor: pointer;
  transition: background-color 0.18s ease;
  margin: 0;
}

.switch::after {
  content: "";
  position: absolute;
  top: 2.5px;
  left: 2.5px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
  transition: transform 0.18s ease;
}

.switch:checked { background: var(--inverse-bg); }
.switch:checked::after { transform: translateX(17px); background: var(--inverse-text); }

.menu-info {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 10.5px;
  line-height: 1.7;
  color: var(--text-3);
}

.menu-info a { color: var(--text-2); text-decoration: none; }
@media (hover: hover) { .menu-info a:hover { text-decoration: underline; } }

.menu-year { margin-top: 6px; }

/* --------------------------------------------------------------------------
   THE TOOL — the board
   -------------------------------------------------------------------------- */

.container {
  width: 100%;
  max-width: 980px;
  margin: 0 auto;
  padding: 0 20px;
  flex: 1;
}

/* --------------------------------------------------------------------------
   Boards: the name above the board opens the list and what you can do
   -------------------------------------------------------------------------- */

.board-bar {
  display: flex;
  justify-content: center;
  width: 100%;
  margin: 0 0 12px;
}

.boards-wrap { position: relative; }

.board-name {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: min(70vw, 360px);
  height: 34px;
  padding: 0 12px 0 16px;
  border-radius: 999px;
  background: var(--surface);
  font-size: 14px;
  font-weight: 600;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.board-name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board-name .icon { width: 15px; height: 15px; color: var(--text-3); transition: transform 0.18s ease; }
.board-name.open { background: var(--inverse-bg); color: var(--inverse-text); }
.board-name.open .icon { color: inherit; transform: rotate(180deg); }
@media (hover: hover) { .board-name:not(.open):hover { background: var(--surface-3); } }

.boards-menu {
  left: 50%;
  right: auto;
  width: 280px;
  transform: translateX(-50%);
  transform-origin: top center;
  animation-name: boards-in;
}

@keyframes boards-in {
  from { opacity: 0; transform: translateX(-50%) scale(0.96) translateY(-4px); }
  to { opacity: 1; transform: translateX(-50%); }
}

.boards-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 220px;
  overflow-y: auto;
  margin: 0 -8px;
}

.board-item {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 38px;
  padding: 0 10px;
  border-radius: 10px;
  text-align: left;
  font-size: 14px;
}

.board-item-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board-item.active { font-weight: 600; }
.board-item-check svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; display: block; }
@media (hover: hover) { .board-item:hover { background: var(--surface-2); } }

.badge {
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--surface-3);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-2);
}

.board-rename { margin-bottom: 4px; }

.menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: calc(100% + 16px);
  min-height: 38px;
  margin: 0 -8px;
  padding: 0 10px;
  border-radius: 10px;
  text-align: left;
  font-size: 14px;
  transition: background-color 0.13s ease;
}

.menu-item .icon { width: 16px; height: 16px; }
.menu-item:disabled { opacity: 0.35; cursor: default; }
@media (hover: hover) { .menu-item:not(:disabled):hover { background: var(--surface-2); } }
.menu-item.menu-confirm { background: var(--inverse-bg); color: var(--inverse-text); }

.tpl-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 4px 0 8px;
}

.tpl-grid .opt-btn { flex: 1 1 auto; padding: 8px 10px; }

.menu-note {
  margin: 0 0 10px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-2);
}

.menu-link { display: block; margin-top: 8px; }
.menu-gap { margin-top: 8px; }
.midi-vel { margin-top: 12px; }
#midiLearnAll { margin-top: 8px; }

/* First visit: what is behind ✎ */
.tip {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  max-width: 560px;
  margin: 16px 0 0;
  padding: 12px 12px 12px 18px;
  border-radius: 18px;
  background: var(--surface);
  animation: tip-in 0.4s ease 0.6s both;
}

@keyframes tip-in {
  from { opacity: 0.01; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

.tip-text { flex: 1; margin: 0; font-size: 13.5px; line-height: 1.45; color: var(--text-2); }
.tip-actions { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.tip .pill-btn { height: 36px; padding: 0 16px; font-size: 13.5px; }
.tip .icon-btn { width: 34px; height: 34px; background: transparent; }
.tip .icon-btn .icon { width: 16px; height: 16px; }

/* Empty pads say what they are for */
.pad.empty .pad-label { color: var(--text-3); margin-top: 2cqmin; }

/* MIDI on a pad: under the shortcut */
.ed-midi { margin-top: 14px; }

/* Two actions in a toast sit apart */
.toast-action + .toast-action { margin-left: 12px; }

/* --------------------------------------------------------------------------
   Sound pages (/lyd/…): one sound, one big pad, a few words, the way back
   -------------------------------------------------------------------------- */

a.pill-btn { text-decoration: none; }
.page-open { height: 36px; padding: 0 16px; font-size: 13.5px; }

.page {
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  padding: 4px 20px 40px;
  flex: 1;
}

.crumbs { font-family: var(--font-mono); font-size: 11px; color: var(--text-3); }
.crumbs a { color: var(--text-2); text-decoration: none; }
@media (hover: hover) { .crumbs a:hover { text-decoration: underline; } }

.page h1 { margin: 10px 0 6px; font-size: clamp(30px, 7vw, 44px); line-height: 1.1; letter-spacing: -0.025em; }
.page .lead { margin: 0 0 24px; font-size: 17px; color: var(--text-2); }
.page h2 { margin: 30px 0 8px; font-size: 18px; letter-spacing: -0.01em; }
.page p, .page li { line-height: 1.6; color: var(--text-2); }
.page .uses { padding-left: 20px; margin: 0; }

.hero-pad {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: min(240px, 70vw);
  aspect-ratio: 1;
  margin: 8px auto 28px;
  border-radius: 32px;
  background: var(--surface);
  overflow: hidden;
  touch-action: manipulation;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  transition: transform 0.12s ease;
}

.hero-pad:active { transform: scale(0.96); }
.hero-pad > span { position: relative; pointer-events: none; }
.hero-icon { font-size: 88px; line-height: 1; }
.hero-label { font-size: 14px; font-weight: 600; color: var(--text-2); }

.hero-fill {
  position: absolute !important;
  inset: 0;
  background: var(--pad-fill);
  transform-origin: left center;
  transform: scaleX(0);
}

.hero-pad.playing .hero-fill { animation: hero-sweep var(--dur, 1s) linear forwards; }
.hero-pad::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 3px var(--text);
  opacity: 0;
  transition: opacity 0.18s ease;
  pointer-events: none;
}
.hero-pad.playing::after { opacity: 1; }

@keyframes hero-sweep {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

.page-cta {
  margin: 30px 0 0;
  padding: 20px;
  border-radius: 20px;
  background: var(--surface);
  text-align: center;
}

.page-cta p { margin: 10px 0 0; font-size: 14px; }

.sound-links {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sound-links a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 14px;
  background: var(--surface);
  color: var(--text);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  transition: background-color 0.13s ease;
}

.sound-links span { font-size: 20px; }
@media (hover: hover) { .sound-links a:hover { background: var(--surface-3); } }
.sound-links-big a { padding: 16px; font-size: 15px; }

/* The soundboard is an instrument, not a page of text. On iPhone a long
   press — and the fast double/triple taps of a stutter («yo-yo-yo») —
   selected the WHOLE page with the copy callout; making only the board
   unselectable was not enough. So nothing on the app page selects (app.js
   also cancels `selectstart`), except the fields, which stay editable.
   The sound pages (/lyd) keep their prose selectable. */
body:not(.sound-page) {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

body:not(.sound-page) input,
body:not(.sound-page) textarea,
body:not(.sound-page) [contenteditable] {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

.stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-top: 4px;
  padding-bottom: 4px;
}

/* The board keeps the grid's own aspect ratio and fits the viewport height:
   width is the smaller of the column and «what the height allows», with a
   floor so very tall grids scroll instead of shrinking to nothing */
.board {
  --gap: clamp(6px, 0.9vmin + 3px, 14px);
  container-type: inline-size;
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  grid-template-rows: repeat(var(--rows), minmax(0, 1fr));
  gap: var(--gap);
  --avail-h: calc(100dvh - 214px);
  width: min(100%, max(calc(var(--cols) * 54px), calc(var(--avail-h) * var(--cols) / var(--rows))));
  aspect-ratio: var(--cols) / var(--rows);
  touch-action: manipulation;
}

/* Portrait phones: full width, and pads may grow up to 40 % taller than
   wide — bigger targets instead of half a screen of nothing below */
@media (max-width: 600px) and (orientation: portrait) {
  .board {
    width: 100%;
    aspect-ratio: auto;
    height: max(calc(var(--rows) * 54px), min(var(--avail-h), calc((100vw - 40px) * var(--rows) / var(--cols) * 1.4)));
  }
}

.pad {
  position: relative;
  container-type: size;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: var(--surface);
  border-radius: clamp(8px, calc(17cqi / var(--cols)), 22px);
  overflow: hidden;
  touch-action: manipulation;
  -webkit-touch-callout: none;
  transition: background-color 0.15s ease, opacity 0.2s ease;
}

.pad > * { position: relative; pointer-events: none; }

@media (hover: hover) {
  .pad:hover { background: var(--pad-hover); }
}

/* Playback: a sweep fills the pad left to right, a ring marks it live */
.pad-fill {
  position: absolute !important;
  inset: 0;
  background: var(--pad-fill);
  transform-origin: left center;
  transform: scaleX(var(--p, 0));
  will-change: transform;
}

/* the sweep fades out where it stopped; a new start shows it instantly */
.pad:not(.playing) .pad-fill { opacity: 0; transition: opacity 0.35s ease; }

.pad::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 2px var(--text);
  opacity: 0;
  transition: opacity 0.18s ease;
  pointer-events: none;
}

.pad.playing::after { opacity: 1; }

.pad-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: min(38cqw, 34cqh);
  line-height: 1;
  height: 1.15em;
  /* emoji glyphs carry their own colour; this keeps text icons on-palette */
  color: var(--text);
  transition: transform 0.2s cubic-bezier(0.2, 0.9, 0.3, 1.3);
}

.pad-icon svg {
  width: 0.92em;
  height: 0.92em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.pad-label {
  max-width: 88%;
  margin-top: 6cqmin;
  font-size: clamp(9.5px, min(12.5cqw, 10.5cqh), 15px);
  font-weight: 500;
  line-height: 1.25;
  color: var(--text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pad-key {
  position: absolute !important;
  top: max(5px, 6.5cqmin);
  left: max(5px, 6.5cqmin);
  min-width: 1.9em;
  padding: 0.12em 0.45em;
  border-radius: 6px;
  background: var(--surface-2);
  font-family: var(--font-mono);
  font-size: clamp(8.5px, 8.5cqmin, 12px);
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: 0.02em;
  text-align: center;
  color: var(--text-3);
  transition: background-color 0.15s ease, color 0.15s ease;
}

.pad.playing .pad-key { background: var(--inverse-bg); color: var(--inverse-text); }

.board.no-keys .pad-key { display: none; }

/* Small pads drop the label, tiny pads the key badge too */
@container (max-height: 76px) { .pad-label { display: none; } }
@container (max-height: 50px) { .pad-key { display: none; } }

/* dim only if a sound is still not ready after a moment (no flash on load) */
.pad.loading .pad-icon { animation: loading-dim 0.3s ease 0.4s both; }
@keyframes loading-dim { to { opacity: 0.35; } }

.pad.empty {
  background: transparent;
  outline: 1.5px dashed var(--border-strong);
  outline-offset: -1.5px;
}

.pad.empty .pad-icon { color: var(--text-3); font-size: 22cqmin; }
.pad.empty .pad-icon svg { stroke-width: 1.6; }

@media (hover: hover) {
  .pad.empty:hover { background: var(--surface); }
}

/* Edit mode: every pad is a target; a pencil marks it, drag to move */
.pad-edit {
  position: absolute !important;
  top: max(5px, 6.5cqmin);
  right: max(5px, 6.5cqmin);
  width: clamp(16px, 15cqmin, 24px);
  height: clamp(16px, 15cqmin, 24px);
  display: none;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--inverse-bg);
  color: var(--inverse-text);
}

.pad-edit svg {
  width: 58%;
  height: 58%;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.board.editing .pad:not(.empty) .pad-edit { display: flex; }
.board.editing .pad:not(.empty) { cursor: grab; }
.board.editing .pad { touch-action: none; }

.board.editing .pad:not(.empty)::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  outline: 1.5px dashed var(--border-strong);
  outline-offset: -1.5px;
  pointer-events: none;
}

.pad.dragging { opacity: 0.3; }

.pad.drop-target { background: var(--surface); }
.pad.drop-target::after { opacity: 1; }

.pad-ghost {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 80;
  margin: 0;
  pointer-events: none;
  box-shadow: var(--shadow-overlay);
  opacity: 0.96;
  transition: none;
}

.hint {
  margin: 16px 0 0;
  max-width: 100%;
  font-family: var(--font-mono);
  font-size: 10.5px;
  line-height: 1.6;
  letter-spacing: 0.02em;
  text-align: center;
  color: var(--text-3);
  -webkit-user-select: none;
  user-select: none;
}

/* Header: stop-all appears while something plays */
.stop-btn { background: var(--inverse-bg); color: var(--inverse-text); }
@media (hover: hover) { .stop-btn:hover { background: var(--inverse-bg); opacity: 0.85; } }
.stop-btn:not([hidden]) { animation: pop-in 0.2s cubic-bezier(0.2, 0.9, 0.3, 1.3); }
.stop-btn .icon { width: 16px; height: 16px; }

@keyframes pop-in {
  from { opacity: 0.01; transform: scale(0.6); }
  to { opacity: 1; transform: scale(1); }
}

/* Settings: grid steppers as label + [− n +] rows */
.menu-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 14px;
}

.menu-row + .menu-row { margin-top: 10px; }

.stepper {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: var(--surface-2);
  flex-shrink: 0;
}

.step-btn {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text);
  transition: background-color 0.13s ease, transform 0.13s ease, opacity 0.13s ease;
}

.step-btn .icon { width: 14px; height: 14px; stroke-width: 2; }
@media (hover: hover) { .step-btn:hover { background: var(--surface); } }
.step-btn:active { transform: scale(0.92); }
.step-btn:disabled { opacity: 0.3; cursor: default; background: none; }

.step-val {
  min-width: 26px;
  text-align: center;
  font-size: 14px;
  font-weight: 600;
}

.menu-toggle + .menu-toggle { margin-top: 14px; }

.menu-confirm { background: var(--inverse-bg); color: var(--inverse-text); }
@media (hover: hover) { .opt-btn.menu-confirm:hover { background: var(--inverse-bg); color: var(--inverse-text); opacity: 0.85; } }

/* Sliders: hairline track with an ink fill up to the thumb (--fill) */
.range {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 26px;
  margin: 0;
  background: transparent;
  cursor: pointer;
  --fill: 50%;
}

.range::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(to right, var(--text) var(--fill), var(--surface-3) var(--fill));
}

.range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  margin-top: -8px;
  border-radius: 50%;
  background: var(--thumb);
  box-shadow: 0 0 0 1px var(--border-strong), 0 1px 4px rgba(0, 0, 0, 0.18);
  transition: transform 0.13s ease;
}

.range:active::-webkit-slider-thumb { transform: scale(1.12); }

.range::-moz-range-track { height: 4px; border-radius: 999px; background: var(--surface-3); }
.range::-moz-range-progress { height: 4px; border-radius: 999px; background: var(--text); }
.range::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border: 0;
  border-radius: 50%;
  background: var(--thumb);
  box-shadow: 0 0 0 1px var(--border-strong), 0 1px 4px rgba(0, 0, 0, 0.18);
}

.range:focus-visible { outline: none; }
.range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 2px var(--text); }
.range:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 2px var(--text); }

/* --------------------------------------------------------------------------
   Pad editor (dialog; a bottom sheet on phones)
   -------------------------------------------------------------------------- */

.sheet {
  border: 0;
  padding: 0;
  margin: auto;
  width: min(460px, calc(100vw - 32px));
  max-width: none;
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--surface);
  color: var(--text);
  border-radius: 24px;
  box-shadow: var(--shadow-overlay);
}

.sheet:focus { outline: none; }

.sheet::backdrop {
  background: rgba(0, 0, 0, 0.3);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}

.sheet[open] { animation: sheet-in 0.22s cubic-bezier(0.2, 0.9, 0.3, 1); }
.sheet[open]::backdrop { animation: fade-in 0.22s ease; }
.sheet.closing { animation: sheet-out 0.16s ease forwards; }
.sheet.closing::backdrop { animation: fade-out 0.16s ease forwards; }

@keyframes sheet-in {
  from { opacity: 0.01; transform: translateY(10px) scale(0.98); }
  to { opacity: 1; transform: none; }
}

@keyframes sheet-out {
  to { opacity: 0; transform: translateY(8px) scale(0.98); }
}

@keyframes fade-in { from { opacity: 0; } }
@keyframes fade-out { to { opacity: 0; } }

.sheet-inner {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 20px;
}

.ed-head {
  display: flex;
  align-items: center;
  gap: 14px;
}

.ed-preview {
  position: relative;
  flex-shrink: 0;
  width: 64px;
  height: 64px;
  border-radius: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2);
  font-size: 32px;
  line-height: 1;
  transition: transform 0.15s ease, background-color 0.15s ease;
}

.ed-preview:active { transform: scale(0.95); }
@media (hover: hover) { .ed-preview:hover { background: var(--surface-3); } }
.ed-preview[disabled] { cursor: default; }
.ed-preview[disabled] .ed-play { display: none; }

.ed-preview-icon svg {
  display: block;
  width: 30px;
  height: 30px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.ed-play {
  position: absolute;
  right: -5px;
  bottom: -5px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--inverse-bg);
  color: var(--inverse-text);
  box-shadow: 0 0 0 3px var(--surface);
}

.ed-play .icon { width: 11px; height: 11px; margin-left: 1px; }
.ed-preview.playing .ed-play { animation: pulse 0.9s ease-in-out infinite; }

@keyframes pulse {
  50% { transform: scale(1.12); }
}

.ed-head-text {
  flex: 1;
  min-width: 0;
}

.ed-head-text .menu-label { margin-bottom: 6px; }

.ed-close { flex-shrink: 0; align-self: flex-start; background: var(--surface-2); }

.ed-input {
  display: block;
  width: 100%;
  font: inherit;
  font-size: 16px; /* 16px+: iOS does not zoom on focus */
  color: var(--text);
  background: var(--surface-2);
  border: 0;
  border-radius: 12px;
  padding: 10px 14px;
  outline: none;
  transition: box-shadow 0.15s ease;
}

.ed-input:focus { box-shadow: inset 0 0 0 1.5px var(--text); }
.ed-input::placeholder { color: var(--text-3); }

.ed-name { font-weight: 600; }

.ed-section > .menu-select { text-overflow: ellipsis; }

/* Instrument pads: note, octave, chord */
.note-row {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr 1.6fr;
  gap: 8px;
  margin-top: 8px;
}

.note-row .menu-select { min-width: 0; padding-right: 34px; background-position: right 12px center; text-overflow: ellipsis; }

/* Sound sources: upload a file, or record one */
.ed-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 8px;
}

.ed-actions .pill-btn { height: 42px; padding: 0 14px; font-size: 14px; }
.ed-actions.single { grid-template-columns: 1fr; } /* no recording in this browser */
.ed-actions .icon { width: 16px; height: 16px; }

/* Recording in progress: live dot, time, level, cancel, stop */
.rec {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 42px;
  margin-top: 8px;
  padding: 0 4px 0 16px;
  border-radius: 999px;
  background: var(--surface-2);
}

.rec-dot {
  flex-shrink: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent); /* live recording: the accent's «critical» job */
  animation: rec-blink 1.2s ease-in-out infinite;
}

@keyframes rec-blink { 50% { opacity: 0.3; } }

.rec-time { min-width: 2.6em; font-size: 14px; font-weight: 600; }

.rec-meter {
  flex: 1;
  height: 4px;
  border-radius: 999px;
  background: var(--surface-3);
  overflow: hidden;
}

.rec-level {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--text);
  transform-origin: left center;
  transform: scaleX(var(--lvl, 0));
}

.rec-cancel { width: 34px; height: 34px; background: transparent; flex-shrink: 0; }
.rec-cancel .icon { width: 16px; height: 16px; }
.rec-stop { height: 34px; padding: 0 14px; font-size: 13.5px; flex-shrink: 0; }
.rec-stop .icon { width: 12px; height: 12px; }

/* Input switcher under the recorder (only with more than one microphone) */
.rec-mic { margin-top: 8px; text-overflow: ellipsis; }

/* Trim, the Voice Memos way: the waveform as rounded bars, the kept part
   framed by two handles, the rest dimmed, a playhead while it plays.
   Handles sit OUTSIDE the kept part, so the track is inset by their width */
.trim-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.trim-head .menu-label { flex: 1; margin-bottom: 8px; }
.trim-time { font-size: 12px; color: var(--text-2); }

.trim {
  position: relative;
  height: 84px;
  padding: 0 14px;
  border-radius: 14px;
  background: var(--surface-2);
  touch-action: none;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}

.trim-track { position: relative; height: 100%; }

.trim-wave {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.trim-sel {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--l, 0%);
  right: var(--r, 0%);
  border-top: 3px solid var(--text);
  border-bottom: 3px solid var(--text);
  pointer-events: none;
}

.trim-handle {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--text);
  cursor: ew-resize;
  touch-action: none;
  outline: none;
}

.trim-handle.start { left: calc(var(--l, 0%) - 14px); border-radius: 10px 0 0 10px; }
.trim-handle.end { left: calc(100% - var(--r, 0%)); border-radius: 0 10px 10px 0; }

/* a bigger invisible grip for fingers */
.trim-handle::after { content: ""; position: absolute; inset: 0 -12px; }

.trim-handle span {
  width: 2px;
  height: 22px;
  border-radius: 1px;
  background: var(--inverse-text);
  opacity: 0.7;
}

.trim-handle:focus-visible { box-shadow: 0 0 0 3px var(--ring); }
.trim.dragging .trim-handle { cursor: grabbing; }

.trim-play {
  position: absolute;
  top: -4px;
  bottom: -4px;
  left: var(--x, 0%);
  width: 3px;
  margin-left: -1.5px;
  border-radius: 2px;
  background: var(--surface);
  box-shadow: 0 0 0 1px var(--text); /* reads on the bars and between them, in both themes */
  pointer-events: none;
}

.fx-label { margin-top: 18px; }

/* Effects on own sounds: chips that combine, and a pitch slider that fills
   from the middle (0 = the sound as recorded) */
.fx-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.fx-grid .opt-btn {
  padding: 9px 8px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pitch-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-top: 16px;
}

.pitch-head .menu-label { margin-bottom: 4px; }

.pitch-val {
  min-width: 2.6em;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  text-align: center;
  color: var(--text-2);
  transition: background-color 0.13s ease, color 0.13s ease;
}

.pitch-val.moved { background: var(--inverse-bg); color: var(--inverse-text); }

.range.bipolar::-webkit-slider-runnable-track {
  background: linear-gradient(to right, var(--surface-3) var(--a, 50%), var(--text) var(--a, 50%),
    var(--text) var(--b, 50%), var(--surface-3) var(--b, 50%));
}

.range.bipolar::-moz-range-progress { background: transparent; }

.range.bipolar::-moz-range-track {
  background: linear-gradient(to right, var(--surface-3) var(--a, 50%), var(--text) var(--a, 50%),
    var(--text) var(--b, 50%), var(--surface-3) var(--b, 50%));
}

/* A fresh board deals itself in, pad by pad */
.board.deal .pad {
  animation: deal-in 0.34s cubic-bezier(0.2, 0.9, 0.3, 1.25) both;
  animation-delay: calc(var(--n, 0) * 12ms);
}

@keyframes deal-in {
  from { opacity: 0.01; transform: scale(0.86); }
  to { opacity: 1; transform: none; }
}

/* A toast can carry one action («Angre») */
.toast-action {
  margin-left: 14px;
  font-weight: 600;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Note and chord symbols as the pad icon («C4», «Am7»): type, not emoji */
.pad-icon.txt,
.ed-preview-icon.txt {
  font-family: var(--font-sans);
  font-weight: 650;
  letter-spacing: -0.03em;
  white-space: nowrap;
}

.pad-icon.txt { font-size: calc(min(38cqw, 34cqh) * var(--k, 1)); }
.ed-preview-icon.txt { font-size: calc(30px * var(--k, 1)); color: var(--text); }

.icon-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(40px, 1fr));
  gap: 6px;
  max-height: 140px;
  overflow-y: auto;
  margin-bottom: 10px;
  padding: 2px;
  overscroll-behavior: contain;
}

.icon-opt {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  background: var(--surface-2);
  font-size: 21px;
  line-height: 1;
  transition: background-color 0.13s ease, transform 0.13s ease, box-shadow 0.13s ease;
}

.icon-opt svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (hover: hover) { .icon-opt:hover { background: var(--surface-3); } }
.icon-opt:active { transform: scale(0.92); }
.icon-opt.active { box-shadow: inset 0 0 0 2px var(--text); background: var(--surface); }

.ed-cols {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 24px;
  align-items: start;
}

.ed-key-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 42px;
}

.key-btn {
  min-width: 52px;
  height: 42px;
  padding: 0 14px;
  border-radius: 12px;
  background: var(--surface-2);
  font-family: var(--font-mono);
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  transition: background-color 0.13s ease, color 0.13s ease;
}

@media (hover: hover) { .key-btn:hover { background: var(--surface-3); } }

.key-btn.capturing {
  background: var(--inverse-bg);
  color: var(--inverse-text);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
}

.key-btn.none { color: var(--text-3); font-family: var(--font-sans); font-size: 13px; font-weight: 500; }

.link-btn {
  font-size: 13px;
  color: var(--text-2);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--border-strong);
}

@media (hover: hover) { .link-btn:hover { color: var(--text); } }

.ed-cols .range { margin-top: 8px; }

.ed-loop { margin-top: 16px; }

.ed-foot {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding-top: 2px;
}

.ed-foot .pill-btn .icon { width: 16px; height: 16px; }

/* Drag & drop of audio files */
.drop-veil {
  position: fixed;
  inset: 0;
  z-index: 70;
  pointer-events: none;
  box-shadow: inset 0 0 0 3px var(--text);
  opacity: 0;
  transition: opacity 0.15s ease;
}

.drop-veil.show { opacity: 1; }

/* --------------------------------------------------------------------------
   Toast
   -------------------------------------------------------------------------- */

.toast {
  position: fixed;
  inset: auto; /* resets popover UA styling (inset: 0) */
  margin: 0;
  border: 0;
  bottom: calc(24px + env(safe-area-inset-bottom));
  left: 50%;
  transform: translate(-50%, 16px);
  background: var(--inverse-bg);
  color: var(--inverse-text);
  font-size: 14px;
  font-weight: 500;
  padding: 12px 22px;
  border-radius: 999px;
  box-shadow: var(--shadow-overlay);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s ease, transform 0.22s ease;
  z-index: 100;
  max-width: calc(100vw - 40px);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.toast.show { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer {
  text-align: center;
  padding: 24px 20px calc(24px + env(safe-area-inset-bottom));
  font-family: var(--font-mono);
  font-size: 10.5px;
  line-height: 1.9;
  letter-spacing: 0.02em;
  color: var(--text-3);
}

.site-footer p { margin: 0; }
.site-footer a { color: var(--text-2); text-decoration: none; }
@media (hover: hover) { .site-footer a:hover { text-decoration: underline; } }

/* --------------------------------------------------------------------------
   Mobile
   -------------------------------------------------------------------------- */

@media (max-width: 600px) {
  .menu { width: min(296px, calc(100vw - 32px)); }

  .stage { justify-content: flex-start; padding-top: 8px; }

  /* The editor becomes a bottom sheet */
  .sheet {
    width: 100%;
    margin: auto 0 0;
    max-height: 92dvh;
    border-radius: 24px 24px 0 0;
  }

  .sheet-inner { padding-bottom: calc(20px + env(safe-area-inset-bottom)); }
  .sheet[open] { animation-name: sheet-up; }
  .sheet.closing { animation-name: sheet-down; }
}

/* Four header buttons (stop, shuffle, edit, settings) beside the brand on
   a 360 px phone */
@media (max-width: 400px) {
  .header-inner { padding: 0 16px; }
  .header-actions { gap: 6px; }
  .header-actions .icon-btn { width: 38px; height: 38px; }
}

@media (max-width: 340px) {
  .ed-cols { grid-template-columns: 1fr; gap: 20px; }
}

@keyframes sheet-up {
  from { transform: translateY(100%); }
  to { transform: none; }
}

@keyframes sheet-down {
  to { transform: translateY(100%); }
}
