/* ==========================================================================
   Scribe — project styles.
   Everything here is built from the kit tokens; kit.css is never touched.
   Material rule kept from the kit: the nav is glass, all content is opaque.
   ========================================================================== */

* { box-sizing: border-box; }

/* The browser's own rule for [hidden] is display:none with no weight, so any
   class that sets a display wins over it. Measured: #blocker, the empty state
   and the skeletons all rendered while marked hidden. Every hidden state in
   this app relies on the attribute, so it is forced here once. */
[hidden] { display: none !important; }

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

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--k-bg);
  color: var(--k-text);
  font-family: var(--k-font);
  font-size: var(--k-fs-md);
  line-height: var(--k-lh);
  -webkit-font-smoothing: antialiased;
}

svg { width: 100%; height: 100%; display: block; }

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

.screen {
  width: min(760px, calc(100% - var(--k-sp-8)));
  margin: 0 auto;
  padding: var(--k-sp-8) 0 calc(var(--k-sp-12) + env(safe-area-inset-bottom));
}

.screen--center {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding-block: var(--k-sp-6);
}

/* --- Sign in -------------------------------------------------------------- */

.login { width: min(380px, 100%); }
.login .k-card__body { display: grid; gap: var(--k-sp-4); }

.login__mark {
  width: 46px; height: 46px;
  padding: 11px;
  border-radius: var(--k-r-md);
  background: var(--k-surface-sunken);
  color: var(--k-accent-text);
}

.login__title {
  margin: 0;
  font-size: var(--k-fs-2xl);
  line-height: var(--k-lh-title);
  letter-spacing: var(--k-track-title);
  font-weight: var(--k-fw-semibold);
}

.login__sub {
  margin: calc(var(--k-sp-3) * -1) 0 var(--k-sp-2);
  color: var(--k-text-2);
  font-size: var(--k-fs-sm);
  line-height: var(--k-lh-ui);
}

.login__submit { width: 100%; }

/* Instance badge: visible enough to register, quiet enough not to become the
   loudest thing on a screen whose subject is the record button. */
.env-badge {
  vertical-align: middle;
  margin-left: var(--k-sp-2);
  letter-spacing: var(--k-track-caps);
  text-transform: uppercase;
  font-size: var(--k-fs-2xs);
  font-weight: var(--k-fw-semibold);
}

/* --- Recorder ------------------------------------------------------------- */

.studio {
  display: grid;
  justify-items: center;
  gap: var(--k-sp-4);
  padding: var(--k-sp-10) var(--k-sp-5) var(--k-sp-8);
  border-radius: var(--k-r-2xl);
  background: var(--k-surface);
  box-shadow: var(--k-shadow-2);
}

/* Level meter: the visible proof that the microphone is actually picking
   the voice up. Bars are driven from JS, one custom property each. */
.meter {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  height: 44px;
  width: min(320px, 90%);
}

.meter__bar {
  flex: 1 1 0;
  max-width: 5px;
  height: max(4px, calc(var(--level, 0) * 44px));
  border-radius: var(--k-r-pill);
  background: var(--k-line-strong);
  transition: height 90ms linear, background-color var(--k-t-fast) var(--k-ease);
}

.meter[data-live="true"] .meter__bar { background: var(--k-danger); }

.timer {
  margin: 0;
  font-size: var(--k-fs-4xl);
  line-height: var(--k-lh-display);
  letter-spacing: var(--k-track-display);
  font-weight: var(--k-fw-regular);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.studio__state {
  margin: calc(var(--k-sp-3) * -1) 0 0;
  color: var(--k-text-2);
  font-size: var(--k-fs-sm);
  line-height: var(--k-lh-ui);
  letter-spacing: 0.01em;
  min-height: 1.35em;
}

.controls {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--k-sp-4);
  width: min(340px, 100%);
  margin-top: var(--k-sp-2);
}

/* Signature control: an iOS-grammar record button. The inner shape morphs
   from a disc to a rounded square instead of swapping icon for icon. */
.rec {
  grid-column: 2;
  position: relative;
  display: grid;
  place-items: center;
  width: 84px; height: 84px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.rec__ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 3px solid var(--k-line-strong);
  background: var(--k-surface);
  box-shadow: var(--k-shadow-1);
  transition: transform var(--k-t) var(--k-ease-spring),
              border-color var(--k-t) var(--k-ease);
  /* Scaled from the live input level while recording. */
  transform: scale(calc(1 + var(--pulse, 0) * 0.06));
}

.rec__shape {
  position: relative;
  width: 62px; height: 62px;
  border-radius: 50%;
  background: var(--k-danger);
  transition: width var(--k-t) var(--k-ease-spring),
              height var(--k-t) var(--k-ease-spring),
              border-radius var(--k-t) var(--k-ease-spring),
              opacity var(--k-t-fast) var(--k-ease);
}

.rec:hover .rec__shape { opacity: 0.86; }
.rec:active .rec__shape { opacity: 0.7; }

.rec:focus-visible { outline: var(--k-focus-ring); outline-offset: 4px; }

.rec[data-state="recording"] .rec__shape,
.rec[data-state="paused"] .rec__shape {
  width: 30px; height: 30px;
  border-radius: 9px;
}

.rec[data-state="recording"] .rec__ring { border-color: var(--k-danger); }
.rec[data-state="paused"] .rec__shape { opacity: 0.45; }

.rec[disabled] { cursor: not-allowed; }
.rec[disabled] .rec__shape { background: var(--k-line-strong); }

/* Side controls sit flat next to the record button so nothing competes
   with it. Label under glyph, iOS style. */
.ctl {
  display: grid;
  justify-items: center;
  gap: 5px;
  min-width: 64px;
  min-height: 48px;
  padding: var(--k-sp-2);
  border: none;
  border-radius: var(--k-r-md);
  background: none;
  color: var(--k-text-2);
  font-family: inherit;
  font-size: var(--k-fs-xs);
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background-color var(--k-t-fast) var(--k-ease),
              color var(--k-t-fast) var(--k-ease);
}

.ctl:hover { background: var(--k-surface-sunken); color: var(--k-text); }
.ctl:focus-visible { outline: var(--k-focus-ring); outline-offset: var(--k-focus-offset); }
.ctl--side:first-of-type { grid-column: 1; justify-self: end; }
.ctl--side:last-of-type { grid-column: 3; justify-self: start; }
.ctl__glyph { width: 22px; height: 22px; }

.studio__foot {
  display: grid;
  justify-items: center;
  gap: var(--k-sp-3);
  width: min(340px, 100%);
  margin-top: var(--k-sp-2);
}

.mic-picker { width: 100%; }

.upload-state {
  margin: 0;
  color: var(--k-text-2);
  font-size: var(--k-fs-xs);
  letter-spacing: 0.01em;
}

.upload-state[data-tone="warn"] { color: var(--k-warning); }

.blocker { max-width: 460px; margin: 0 auto; }
.blocker .k-empty__icon { color: var(--k-warning); }

/* --- Library -------------------------------------------------------------- */

.library { margin-top: var(--k-sp-10); }

.library__head {
  display: flex;
  align-items: center;
  gap: var(--k-sp-3);
  margin-bottom: var(--k-sp-4);
  padding-inline: var(--k-sp-1);
}

.library__title {
  margin: 0;
  font-size: var(--k-fs-xl);
  line-height: var(--k-lh-title);
  letter-spacing: var(--k-track-title);
  font-weight: var(--k-fw-semibold);
}

.library__list { display: grid; gap: var(--k-sp-3); }

.item .k-card__body { display: grid; gap: var(--k-sp-3); }

.item__head {
  display: flex;
  align-items: flex-start;
  gap: var(--k-sp-3);
}

.item__title {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: var(--k-fs-lg);
  line-height: var(--k-lh-snug);
  letter-spacing: var(--k-track-snug);
  font-weight: var(--k-fw-medium);
  overflow-wrap: anywhere;
}

.item__meta {
  margin: 3px 0 0;
  color: var(--k-text-2);
  font-size: var(--k-fs-sm);
  line-height: var(--k-lh-ui);
  font-variant-numeric: tabular-nums;
}

.item__actions { display: flex; gap: var(--k-sp-1); flex-shrink: 0; }

/* Row actions stay quiet: the only saturated element on this screen is the
   record button. The kit's ghost variant tints icons with the accent and its
   danger variant fills them, which would put eight loud dots on a list of
   four recordings. Colour arrives on hover instead. */
.item__actions .k-btn {
  background: transparent;
  color: var(--k-text-2);
}

.item__actions .k-btn:hover {
  background: var(--k-surface-sunken);
  color: var(--k-text);
}

.item__actions .k-btn--danger:hover {
  background: color-mix(in srgb, var(--k-danger) 12%, transparent);
  color: var(--k-danger);
}

.item audio {
  width: 100%;
  height: 40px;
  border-radius: var(--k-r-pill);
}

/* The transcript is the reason the recording exists, so it gets a surface of
   its own rather than being another line of grey metadata. */
.transcript {
  display: grid;
  gap: var(--k-sp-2);
  padding: var(--k-sp-4);
  border-radius: var(--k-r-md);
  background: var(--k-surface-sunken);
}

.transcript__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--k-sp-3);
}

.transcript__label {
  font-size: var(--k-fs-2xs);
  font-weight: var(--k-fw-semibold);
  letter-spacing: var(--k-track-caps);
  text-transform: uppercase;
  color: var(--k-text-2);
}

.transcript__text {
  margin: 0;
  max-width: 68ch;
  font-size: var(--k-fs-md);
  line-height: var(--k-lh-prose);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.transcript__waiting,
.transcript__failed {
  margin: 0;
  font-size: var(--k-fs-sm);
  line-height: var(--k-lh-ui);
  color: var(--k-text-2);
}

/* A dot that breathes while the server works, so a long job does not look
   like a frozen card. */
.transcript__waiting::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: var(--k-sp-2);
  border-radius: 50%;
  background: var(--k-accent);
  animation: transcript-pulse 1.4s var(--k-ease-inout) infinite;
}

@keyframes transcript-pulse {
  0%, 100% { opacity: 0.25; }
  50% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .transcript__waiting::before { animation: none; opacity: 0.7; }
}

.transcript__failed { color: var(--k-danger); }
.transcript .k-btn--secondary { justify-self: start; }

.item__rename {
  display: flex;
  gap: var(--k-sp-2);
  align-items: center;
}

.item__rename .k-input { flex: 1; }

@media (max-width: 520px) {
  .screen { width: calc(100% - var(--k-sp-6)); }
  .studio { padding: var(--k-sp-8) var(--k-sp-4) var(--k-sp-6); }
  .timer { font-size: var(--k-fs-3xl); }
}

@media (prefers-reduced-motion: reduce) {
  .meter__bar, .rec__ring, .rec__shape { transition-duration: 1ms; }
  .rec__ring { transform: none; }
}
