/*
 * App chrome: authentication, shell, sidebar, header, content region, wizard.
 * The content layer bleeds to the edges; controls stay inside the gutter.
 */

/* ==========================================================================
   Launch
   ========================================================================== */

.launch-screen {
  position: fixed;
  z-index: calc(var(--z-skip) + 1);
  inset: 0;
  display: grid;
  place-items: center;
  min-block-size: 100dvh;
  padding: calc(var(--space-6) + env(safe-area-inset-top)) calc(var(--space-6) + env(safe-area-inset-right))
    calc(var(--space-6) + env(safe-area-inset-bottom)) calc(var(--space-6) + env(safe-area-inset-left));
  background: var(--surface-raised);
  color: var(--text-primary);
}

.launch-wordmark {
  font-size: clamp(1.75rem, 1.5rem + 1vw, 2.25rem);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1;
}

@media (prefers-reduced-motion: no-preference) {
  .launch-screen {
    transition: opacity var(--duration-panel) var(--ease-out);
  }

  .launch-wordmark {
    animation: launch-wordmark 640ms var(--ease-out) both;
  }

  .launch-screen.is-leaving {
    opacity: 0;
    pointer-events: none;
  }

  @keyframes launch-wordmark {
    from {
      opacity: 0;
      scale: 0.985;
    }
    to {
      opacity: 1;
      scale: 1;
    }
  }
}

/* ==========================================================================
   Authentication
   ========================================================================== */

.auth-shell {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 100dvh;
  padding: calc(var(--space-10) + env(safe-area-inset-top)) calc(var(--gutter) + env(safe-area-inset-right))
    calc(var(--space-10) + env(safe-area-inset-bottom)) calc(var(--gutter) + env(safe-area-inset-left));
  overflow-y: auto;
  background: var(--surface-raised);
}

.auth-theme-toggle {
  position: absolute;
  inset-block-start: calc(var(--space-4) + env(safe-area-inset-top));
  inset-inline-end: var(--gutter);
}

.auth-stage {
  inline-size: 100%;
  max-inline-size: 23rem;
}

.auth-panel {
  display: flex;
  flex-direction: column;
  min-inline-size: 0;
}

.auth-panel h1 {
  margin-block-end: var(--space-8);
  font-size: clamp(1.75rem, 1.55rem + 0.75vw, 2rem);
  text-align: center;
}

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

.auth-form .form-input {
  min-block-size: 3rem;
  padding-inline: var(--space-4);
  border-radius: var(--radius-5);
  background: var(--surface-canvas);
  font-size: var(--type-body);
}

.auth-form .btn-lg {
  min-block-size: 3.125rem;
  border-radius: var(--radius-5);
}

.password-control {
  position: relative;
}

.password-control .form-input {
  padding-inline-end: 3.25rem;
}

.password-toggle {
  position: absolute;
  inset-block: 2px;
  inset-inline-end: 2px;
  min-inline-size: 2.75rem;
  min-block-size: auto;
  border-radius: calc(var(--radius-5) - 2px);
}

.password-toggle > svg {
  inline-size: 1.125rem;
  block-size: 1.125rem;
}

@media (max-height: 39rem) and (orientation: landscape) {
  .auth-shell {
    place-items: start center;
  }

  .auth-panel h1 {
    margin-block-end: var(--space-6);
  }
}

/* ==========================================================================
   Shell
   ========================================================================== */

.app-container {
  position: relative;
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  height: max-content;
  min-height: 100dvh;
  background: var(--surface-canvas);
}

/*
 * The sidebar itself stays viewport-sticky, while this structural layer follows
 * the full document height. Long pages therefore never expose a light gap below
 * the dark navigation rail.
 */
.app-container::before {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: var(--sidebar-w);
  background: var(--chrome-bg);
}

.app-container.sidebar-collapsed {
  grid-template-columns: var(--sidebar-w-collapsed) minmax(0, 1fr);
}

.app-container.sidebar-collapsed::before {
  inline-size: var(--sidebar-w-collapsed);
}

.main-wrapper {
  display: flex;
  flex-direction: column;
  min-inline-size: 0;
  min-height: 100dvh;
}

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

.sidebar {
  position: sticky;
  z-index: var(--z-nav);
  inset-block-start: 0;
  display: flex;
  flex-direction: column;
  block-size: 100dvh;
  min-inline-size: 0;
  padding-block: var(--space-4);
  padding-block-end: calc(var(--space-4) + env(safe-area-inset-bottom));
  background: var(--chrome-bg);
  color: var(--chrome-text);
}

.sidebar-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-inline: var(--space-4);
  padding-block-end: var(--space-5);
}

.sidebar .brand-mark {
  background: var(--chrome-text);
  color: var(--chrome-bg);
}

.brand-info {
  min-inline-size: 0;
}

.brand-name {
  font-size: var(--type-lead);
  font-weight: 600;
  letter-spacing: var(--tracking-heading);
}

.brand-role {
  color: var(--chrome-muted);
  font-size: var(--type-caption);
}

.sidebar .icon-button {
  color: var(--chrome-muted);
}

@media (hover: hover) {
  .sidebar .icon-button:hover {
    background: var(--chrome-hover);
    color: var(--chrome-text);
  }
}

.sidebar-collapse {
  margin-inline-start: auto;
}

.sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  flex: 1;
  min-inline-size: 0;
  padding-inline: var(--space-3);
  overflow-y: auto;
}

.nav-label {
  padding-inline: var(--space-3);
  padding-block: var(--space-4) var(--space-2);
  color: var(--chrome-muted);
  font-size: var(--type-caption);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

.nav-label:first-child {
  padding-block-start: 0;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-block-size: var(--hit-min);
  min-inline-size: 0;
  padding-inline: var(--space-3);
  border-radius: var(--radius-4);
  color: var(--chrome-muted);
  font-size: var(--type-ui);
  font-weight: 500;
  text-decoration: none;
}

.nav-item > svg {
  flex: none;
  inline-size: var(--icon-md);
  block-size: var(--icon-md);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.nav-item > span {
  min-inline-size: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.nav-item.active {
  background: var(--chrome-raised);
  color: var(--chrome-text);
  font-weight: 600;
}

.nav-item {
  position: relative;
}

@media (hover: hover) {
  .nav-item:hover {
    background: var(--chrome-hover);
    color: var(--chrome-text);
  }
}

.nav-attention {
  flex: none;
  inline-size: 0.5rem;
  block-size: 0.5rem;
  margin-inline-start: auto;
  border-radius: var(--radius-pill);
  background: var(--warn-500);
}

.nav-count {
  margin-inline-start: auto;
  padding-inline: var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--chrome-hover);
  color: var(--chrome-text);
  font-size: var(--type-caption);
  font-variant-numeric: tabular-nums;
}

.sidebar-footer {
  padding-inline: var(--space-3);
  padding-block-start: var(--space-4);
}

.sidebar-user {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-inline-size: 0;
  padding: var(--space-2);
  border-radius: var(--radius-5);
  background: var(--chrome-raised);
}

.sidebar-user-copy {
  min-inline-size: 0;
  flex: 1;
}

.sidebar-user-copy strong {
  display: block;
  font-size: var(--type-ui);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sidebar-user-copy span {
  display: block;
  color: var(--chrome-muted);
  font-size: var(--type-caption);
}

/* ---------- Collapsed ---------------------------------------------------- */

.sidebar.collapsed .brand-info,
.sidebar.collapsed .nav-item > span,
.sidebar.collapsed .nav-label,
.sidebar.collapsed .sidebar-user-copy,
.sidebar.collapsed .nav-count {
  display: none;
}

.sidebar.collapsed .sidebar-header,
.sidebar.collapsed .sidebar-nav,
.sidebar.collapsed .sidebar-footer {
  padding-inline: var(--space-2);
}

.sidebar.collapsed .nav-item,
.sidebar.collapsed .sidebar-user {
  justify-content: center;
}

/* ---------- Off-canvas on narrow widths --------------------------------- */

/*
 * The scrim is a control: clicking it closes the drawer, so it keeps pointer
 * events. It therefore has to sit below the drawer it dims, otherwise it swallows
 * every tap on a navigation link.
 */
.sidebar-backdrop {
  position: fixed;
  z-index: var(--z-nav);
  inset: 0;
  background: var(--surface-scrim);
}

/*
 * Collapses only where the two columns genuinely stop fitting: a 15.5rem rail
 * plus a readable measure needs about 60rem.
 */
@media (max-width: 60rem) {
  .app-container,
  .app-container.sidebar-collapsed {
    grid-template-columns: minmax(0, 1fr);
  }

  .app-container::before,
  .app-container.sidebar-collapsed::before {
    display: none;
  }

  .sidebar {
    position: fixed;
    /* Above the scrim, which is at --z-nav. */
    z-index: var(--z-overlay);
    inset-block: 0;
    inset-inline-start: 0;
    inline-size: min(18rem, calc(100vw - 2rem));
    translate: -100% 0;
  }

  .sidebar.open {
    translate: 0 0;
    box-shadow: var(--shadow-float);
  }

  .sidebar.collapsed .brand-info,
  .sidebar.collapsed .nav-item > span,
  .sidebar.collapsed .nav-label,
  .sidebar.collapsed .sidebar-user-copy {
    display: revert;
  }

  .sidebar.collapsed .nav-item,
  .sidebar.collapsed .sidebar-user {
    justify-content: flex-start;
  }

  .sidebar-collapse {
    display: none;
  }
}

@media (min-width: 60.01rem) {
  /* The document background closes the last fractional WebKit pixel below long rails. */
  body {
    background: linear-gradient(
      to right,
      var(--chrome-bg) 0 var(--sidebar-w),
      var(--surface-canvas) var(--sidebar-w) 100%
    );
  }

  body:has(.app-container.sidebar-collapsed:not([hidden])) {
    background: linear-gradient(
      to right,
      var(--chrome-bg) 0 var(--sidebar-w-collapsed),
      var(--surface-canvas) var(--sidebar-w-collapsed) 100%
    );
  }

  .mobile-only {
    display: none !important;
  }

  .sidebar-backdrop {
    display: none !important;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .sidebar {
    /* A transition retargets mid-flight; a keyframe restarts and feels broken. */
    transition: translate var(--duration-panel) var(--ease-out);
  }

  .nav-item {
    transition:
      background-color var(--duration-tap) var(--ease-out),
      color var(--duration-tap) var(--ease-out);
  }
}

/* ==========================================================================
   Header
   ========================================================================== */

.top-header {
  position: sticky;
  z-index: var(--z-sticky);
  inset-block-start: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-inline: var(--gutter);
  padding-block: var(--space-3);
  padding-block-start: calc(var(--space-3) + env(safe-area-inset-top));
  background: var(--surface-overlay);
  backdrop-filter: blur(12px);
  border-block-end: 1px solid var(--line-hairline);
}

.header-leading {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-inline-size: 0;
}

.header-leading > div {
  min-inline-size: 0;
}

.header-eyebrow {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.top-header h1 {
  font-size: var(--type-h3);
  overflow-wrap: anywhere;
}

/* The router focuses this heading only to announce a page change. */
#page-title.route-announcement-target:focus-visible {
  outline: none;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-inline-size: 0;
}

.organization-switcher,
.property-switcher {
  min-inline-size: 0;
}

.organization-switcher .form-select,
.property-switcher .form-select {
  max-inline-size: 14rem;
  min-block-size: var(--hit-min);
  font-size: var(--type-caption);
}

/* ==========================================================================
   Content
   ========================================================================== */

.content-area {
  flex: 1;
  min-inline-size: 0;
  padding-inline: var(--gutter);
  padding-block: var(--space-6);
  padding-block-end: calc(var(--space-12) + env(safe-area-inset-bottom));
}

.content-area > * {
  inline-size: min(100%, var(--content-max));
  margin-inline: auto;
}

.content-area > * + * {
  margin-block-start: var(--space-6);
}

/* Long-form reading columns stay inside a comfortable measure. */
.prose {
  max-inline-size: var(--measure);
}

/* A page ends on purpose rather than just stopping. */
.page-footnote {
  padding-block-start: var(--space-6);
  border-block-start: 1px solid var(--line-hairline);
  color: var(--text-tertiary);
  font-size: var(--type-caption);
  line-height: var(--leading-relaxed);
}

.page-grid,
.two-column-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  gap: var(--space-6);
}

.page-grid > *,
.two-column-grid > * {
  min-inline-size: 0;
}

.dashboard-grid,
.metric-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
  gap: var(--space-4);
}

.dashboard-grid > *,
.metric-grid > * {
  min-inline-size: 0;
}

/* Asymmetric on purpose: the primary column leads instead of four equal cards. */
.dashboard-columns {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: var(--space-6);
  align-items: start;
}

@container (max-width: 60rem) {
  .dashboard-columns {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 64rem) {
  .dashboard-columns {
    grid-template-columns: minmax(0, 1fr);
  }
}

.view-loading,
.content-area {
  container-type: inline-size;
}

/* ==========================================================================
   Wizard
   ========================================================================== */

.wizard {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
  gap: var(--space-6);
  align-items: start;
}

@media (max-width: 68rem) {
  .wizard {
    grid-template-columns: minmax(0, 1fr);
  }
}

.wizard-rail {
  position: sticky;
  inset-block-start: calc(4.5rem + env(safe-area-inset-top));
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-inline-size: 0;
  padding: var(--space-3);
  border-radius: var(--radius-7);
  background: var(--surface-raised);
  box-shadow: var(--shadow-raised);
}

@media (max-width: 68rem) {
  .wizard-rail {
    position: static;
    /* Horizontal scroller: the next step peeks past the edge so it reads as scrollable. */
    flex-direction: row;
    overflow-x: auto;
    scroll-snap-type: x proximity;
  }

  .wizard-step {
    flex: 0 0 min(15rem, 78%);
    scroll-snap-align: start;
  }
}

.wizard-step {
  /* Hosts a `.sr-only` state word; see the note in components.css. */
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: var(--space-3);
  min-block-size: var(--hit-min);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-4);
  color: var(--text-secondary);
  font-size: var(--type-ui);
  text-align: start;
  text-decoration: none;
  cursor: pointer;
}

.wizard-step > div {
  min-inline-size: 0;
}

.wizard-step strong {
  display: block;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wizard-step small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wizard-step[aria-current='step'] {
  background: var(--surface-selected);
  color: var(--text-primary);
  box-shadow: inset 0 0 0 1.5px var(--action-solid);
}

@media (hover: hover) {
  .wizard-step:hover:not([aria-current='step']) {
    background: var(--surface-sunken);
    color: var(--text-primary);
  }
}

/* The marker carries state as a glyph, so it survives without colour. */
.wizard-marker {
  display: grid;
  place-items: center;
  flex: none;
  inline-size: 1.5rem;
  block-size: 1.5rem;
  border-radius: var(--radius-pill);
  background: var(--surface-inset);
  color: var(--text-secondary);
  font-size: var(--type-caption);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.wizard-step.is-done .wizard-marker {
  background: var(--status-ok-quiet);
  color: var(--status-ok-ink);
  box-shadow: inset 0 0 0 1px var(--status-ok-line);
}

.wizard-step.is-blocked .wizard-marker {
  background: var(--status-warn-quiet);
  color: var(--status-warn-ink);
  box-shadow: inset 0 0 0 1px var(--status-warn-line);
}

.wizard-marker svg {
  inline-size: 0.875rem;
  block-size: 0.875rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.25;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.wizard-panel {
  min-inline-size: 0;
}

.wizard-progress {
  inline-size: 100%;
  block-size: 0.375rem;
  margin-block-start: var(--space-2);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--surface-inset);
  appearance: none;
}

.wizard-progress::-webkit-progress-bar {
  border-radius: var(--radius-pill);
  background: var(--surface-inset);
}

.wizard-progress::-webkit-progress-value {
  border-radius: var(--radius-pill);
  background: var(--action-solid);
}

.wizard-progress::-moz-progress-bar {
  border-radius: var(--radius-pill);
  background: var(--action-solid);
}

/* ==========================================================================
   Region refresh
   ========================================================================== */

/*
 * A region reloads on its own instead of the router rebuilding the page, so an
 * action never resets the scroll position. It stays at full strength while busy;
 * dimming it would read as "you cannot do this".
 */
[data-region][aria-busy='true'] {
  position: relative;
}

[data-region][aria-busy='true']::after {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 2px;
  border-radius: var(--radius-pill);
  background: var(--action-solid);
  transform-origin: inline-start;
}

@media (prefers-reduced-motion: no-preference) {
  [data-region][aria-busy='true']::after {
    animation: region-progress 1s var(--ease-out) infinite;
  }

  @keyframes region-progress {
    from {
      scale: 0 1;
      opacity: 1;
    }
    to {
      scale: 1 1;
      opacity: 0.2;
    }
  }
}
