/* KimiSoba shared components — the vocabulary every app draws from.
 *
 * Phase 2 of REDESIGN.md. Values come from the scale primitives in
 * tokens.css, so the direction-C swap lands here without edits.
 *
 * Link after tokens.css and before the app stylesheet.
 */

/* --- View header ------------------------------------------------------------
 *
 * Replaces the per-app `.hero` / `.page-head` blocks. Those opened every screen
 * with the app's own name, mark and tagline — roughly 140px before the first
 * number. This says where you are and offers one action, in about 60px.
 * App identity lives in the topbar now.
 */
.view-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin: 0 0 var(--space-4);
}

.view-head-text {
  min-width: 0;
}

.view-kicker {
  margin: 0 0 0.15rem;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}

.view-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.1;
  color: var(--ink);
}

.view-sub {
  margin: var(--space-2) 0 0;
  max-width: 34rem;
  font-size: var(--text-sm);
  line-height: 1.45;
  color: var(--muted);
}

.view-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* --- App identity in the topbar --------------------------------------------
 *
 * The dog mark moves out of the page body and into the chrome, at a size that
 * belongs in a 44px control row rather than a hero.
 */
.suite-topbar .brand .app-mark {
  width: 2rem;
  height: 2rem;
  border-radius: 28%;
}

/* App names ("PamperedKimi", "ThriftyKimi") are longer than the suite wordmark
   they replaced, so the brand must be able to give way before the topbar wraps. */
.suite-topbar .brand {
  min-width: 0;
}

.suite-topbar .brand-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 640px) {
  .suite-topbar .brand .app-mark {
    width: 1.85rem;
    height: 1.85rem;
  }
}

/* Small phones: a third control (Quick Capture) leaves the brand about 8px
   short once the name has already ellipsized. Take it from the bar's own
   padding and gaps rather than dropping the app's identity. */
@media (max-width: 360px) {
  .suite-topbar {
    gap: var(--space-2);
    padding-left: var(--space-3);
    padding-right: var(--space-3);
  }

  .topbar-actions {
    gap: var(--space-1);
  }
}

/* --- Motion -----------------------------------------------------------------
 *
 * Phase 4 of REDESIGN.md. Tab switches were a hard `hidden` toggle in every
 * app: the outgoing view vanished and the incoming one appeared with no
 * continuity. All eight apps mark the visible view `.tab-page.is-active`, so a
 * single enter animation covers the suite without touching any app's switcher.
 *
 * Toggling `hidden` moves the element through display:none, which restarts CSS
 * animations — that is what makes this replay on every switch.
 */
.tab-page.is-active,
.page.is-active {
  animation: view-in var(--dur-base) var(--ease-out) both;
}

@keyframes view-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Sheets rise with a little overshoot rather than easing flatly to a stop. */
.sheet,
.qa-sheet {
  animation: sheet-rise var(--dur-slow) var(--ease-spring) both;
}

@keyframes sheet-rise {
  from {
    transform: translateY(14px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

/* One honest accommodation, rather than a flag each animation has to remember.
 * Before this the suite had no prefers-reduced-motion rule at all. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}


/* --- Shared component base -------------------------------------------------
 *
 * Extracted from the eight app stylesheets: only declarations identical in
 * every app that defined them, in the source order they already shared (all
 * eight ordered related selectors the same way, so relative cascade is
 * preserved). Each app's stylesheet still loads last and still wins wherever
 * it set something different.
 *
 * Selectors the shell's own stylesheets define are NOT here — see base.css.
 */

/* shared by 7 apps */
.btn:active {
  transform: scale(0.98);
}

/* shared by 5 apps */
.btn-text-danger {
  appearance: none;
  border: 0;
  background: none;
  color: var(--danger);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  padding: 0.5rem;
  opacity: 0.9;
}

/* shared by 5 apps */
.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* shared by 7 apps */
.panel {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  backdrop-filter: blur(8px);
  box-shadow: var(--shadow);
}

/* shared by 5 apps */
.panel-head.row {
  display: flex;
  justify-content: space-between;
}

/* shared by 3 apps */
.nav-fab {
  appearance: none;
  border: 0;
  cursor: pointer;
}

/* shared by 3 apps */
.fab-glyph {
  font-weight: 700;
  line-height: 1;
}

/* shared by 3 apps */
.fab-caption {
  font-weight: 700;
}
