/* The shell: a white sidebar headed by the groundhog lockup, the sticky top bar with the ink Run pill, the banner
   under it, the share popover, and the drawer the sidebar becomes on narrow screens. The top row reads as ardana.ai's
   nav: the logo at the top-left, the actions at the right, one hairline beneath. */

.shell {
  display: grid;
  grid-template-columns: var(--sidebar) minmax(0, 1fr);
  min-height: 100vh;
}

/* Collapsed, the sidebar's column goes at once: columns are layout, and nothing on the page animates layout. */
.shell.collapsed {
  grid-template-columns: 0 minmax(0, 1fr);
}

/* The landing's skip link: an ink pill that slides in from above the top-left corner. */
.skip-link {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 70;
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--text-14);
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform var(--normal) var(--ease-out);
}

.skip-link:focus-visible {
  transform: none;
}

/* ---- Sidebar ---- */

.sidebar {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  overflow: hidden auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding-bottom: var(--space-5);
  background: var(--bg);
  /* The one vertical hairline; the head covers its top, so the top row stays one bar. */
  box-shadow: inset -1px 0 0 var(--line);
  color: var(--ink);
}

.shell.collapsed .sidebar {
  visibility: hidden;
}

/* The head: the lockup where the landing's nav puts it, on the top row's hairline. */
.workspace {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--topbar);
  padding: 0 var(--space-3) 0 var(--space-5);
  background: var(--bg);
  box-shadow: inset 0 -1px 0 var(--line);
}

.workspace .logo {
  margin-right: auto;
}

/* The collapse control shows itself when the head is hovered or the sidebar has focus. */
.workspace .button-icon {
  opacity: 0;
  transition:
    opacity var(--fast) ease,
    color var(--fast) ease,
    background-color var(--fast) ease;
}

.workspace:hover .button-icon,
.workspace .button-icon:focus-visible,
.sidebar:focus-within .workspace .button-icon {
  opacity: 1;
}

.sidebar-section {
  display: grid;
  gap: 2px;
  padding: 0 var(--space-3);
}

.sidebar-heading {
  display: flex;
  align-items: center;
  min-height: 28px;
  padding: 0 var(--space-3);
  color: var(--muted);
  font-size: var(--text-13);
  font-weight: 500;
  line-height: 1;
}

.sidebar-section .select {
  margin-top: 2px;
}

.sidebar-section .select-input {
  padding-left: var(--space-3);
}

/* A row: a preset or a section of the page, as the landing's nav sets a link: gray, ink on hover and when current. */
.row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 34px;
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-inner);
  background: transparent;
  color: var(--muted);
  font-size: var(--text-15);
  font-weight: 400;
  line-height: 1.2;
  text-align: left;
  cursor: pointer;
  transition: color var(--fast) ease;
}

.row:hover,
.row:active {
  color: var(--ink);
}

/* The section in view, in the "On this page" list: ink, as the landing marks its current page, and at 500, so it stands
   apart in the dark scheme and in forced colours too, where its ink alone does not. */
.row[aria-current="true"] {
  color: var(--ink);
  font-weight: 500;
}

/* A label wraps rather than cut when text is enlarged. */
.row-label {
  flex: 1;
  min-width: 0;
  padding-block: 6px;
  overflow-wrap: anywhere;
}

/* The landing's back arrow leads "Restore previous", and nudges back on hover. */
.row .icon-back {
  stroke-width: 1.6;
  transform: scaleX(-1);
  transition: transform var(--normal) var(--ease-out);
}

.row:hover .icon-back {
  transform: scaleX(-1) translateX(3px);
}

.sidebar-foot {
  margin-top: auto;
  display: grid;
  gap: 4px;
  padding: 0 var(--space-5);
  color: var(--muted);
  font-size: var(--text-13);
  line-height: 1.45;
}

.sidebar-foot code {
  padding: 0;
  background: transparent;
  color: var(--ink);
  font-size: var(--text-12);
}

/* ---- Main column: top bar, banner, page ---- */

.main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  /* A tooltip near the right edge clips at the page rather than widening it; clip keeps the top bar sticky. */
  overflow-x: clip;
}

/* The bar wraps its actions onto a second line rather than cutting them when text is enlarged. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  min-height: var(--topbar);
  padding: 14px var(--gutter);
  background: var(--bg);
  box-shadow: inset 0 -1px 0 var(--line);
}

/* A bar taller than a third of the viewport scrolls with the page. */
.topbar-loose .topbar {
  position: relative;
}

/* The lockup and the opener join the top bar only while the sidebar is collapsed or a drawer. */
.topbar .opener,
.topbar .topbar-logo {
  display: none;
}

.shell.collapsed .topbar .opener,
.shell.collapsed .topbar .topbar-logo {
  display: inline-flex;
}

.topbar .opener {
  margin-left: -8px;
}

.topbar-logo {
  margin-right: var(--space-3);
}

/* The landing's nav links, 28px apart as there: Pencil Gray, ink for this page and under the pointer. */
.topbar-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 28px;
  min-width: 0;
  flex: 1 1 auto;
  font-size: var(--text-15);
}

.topbar-nav a {
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--fast) ease;
}

.topbar-nav a:hover,
.topbar-nav a[aria-current="page"] {
  color: var(--ink);
}

/* Share and Run never shrink; the stale tag gives way first, then the nav wraps. */
.topbar-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  flex: 0 1 auto;
}

.topbar-actions > .share,
.topbar-actions > .run-key {
  flex: none;
}

/* Share is a word; on the smallest phones a link glyph stands in for it (its name stays "Share link"). */
.share-icon {
  display: none;
}

/* The stale tag in the top bar: nothing while the last run still matches. */
.changed {
  display: flex;
  align-items: center;
  min-width: 0;
  flex: 0 1 auto;
}

.changed .tag {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.changed:not(.on) .tag {
  display: none;
}

/* The banner under the top bar: why Run is held, what a first run is downloading, or where a run in this tab is. A
   wait is gray; a fault is red. */
.banner {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 40px;
  padding: 8px var(--gutter);
  background: var(--danger-tint);
  color: var(--danger);
  font-size: var(--text-14);
  font-weight: 500;
  box-shadow: inset 0 -1px 0 var(--line);
}

.banner:empty {
  display: none;
}

.banner.quiet {
  background: var(--bg);
  color: var(--muted);
}

/* While a run in this tab is in flight the banner is its only progress: it stays right under the top bar, over the
   page, at the bar's rendered height. When the whole banner would take too much of the screen, it sticks higher, its
   words under the bar, so only its last row (the download bar and Stop) shows; past that it scrolls with the page. */
.banner.busy {
  position: sticky;
  top: calc(var(--topbar-height) + var(--banner-stuck) - var(--banner-height));
  z-index: 19;
}

.banner-loose .banner.busy {
  position: static;
}

/* Whatever the page scrolls to meanwhile, focus by Tab or Shift+Tab included, lands under what stays, as tall as it is
   rendered at this width, zoom and text size (WCAG 2.4.11). */
html:has(.banner.busy) {
  scroll-padding-top: calc(var(--topbar-stuck) + var(--banner-stuck) + var(--space-3));
}

/* The way to the ardana CLI's command, for a model this server has not pulled: the landing's forward link, an ink word
   and its arrow, which nudges on hover as Restore previous's does. */
.banner-action {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 24px;
  padding: 0;
  border: 0;
  border-radius: 3px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  cursor: pointer;
}

.banner-action .icon {
  stroke-width: 1.6;
  transition: transform var(--normal) var(--ease-out);
}

.banner-action:hover .icon {
  transform: translateX(3px);
}

/* The banner's actions keep together after its words, 24px apart so the arrow of the first never points at the next:
   the way to the ardana CLI's commands and, in the standalone build, the browser default in this tab instead. Where the
   words and the actions do not fit one line, the actions take the next whole, rather than squeezing the words. */
.banner:has(.banner-actions) {
  flex-wrap: wrap;
}

.banner-actions {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-5);
}

/* Stop ends a run in this tab, and "Run … in this tab instead" picks the browser default's row: the same ink word
   without the arrow, which leads nowhere, underlined on hover as the landing's ink links are. */
.banner-stop:hover,
.banner-instead:hover {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

/* The download bar and Stop keep together after the words. */
.banner-track {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

/* A download into this tab: the answers' 6px pill bar, its track and its gray fill, after the bytes it counts. */
.banner-progress {
  flex: 0 1 160px;
  min-width: 96px;
  height: 6px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--track);
  color: var(--bar);
  overflow: hidden;
  appearance: none;
}

.banner-progress::-webkit-progress-bar {
  border-radius: var(--radius-pill);
  background: var(--track);
}

.banner-progress::-webkit-progress-value {
  border-radius: var(--radius-pill);
  background: var(--bar);
}

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

/* Under the picker, an "In browser" pick says where Run answers and what its first run downloads; a list that did not
   arrive says why, in the fault colour, under the note's alignment. */
.model-note,
.model-fault {
  margin: 6px 0 0;
  padding: 0 var(--space-3);
}

/* ---- Share popover: anchored under the Share button, flat, a hairline around it ---- */

.share {
  position: relative;
}

/* It opens 8px under the top bar's hairline, not across it: the 32px button sits 19px above the bar's foot. */
.popover {
  position: absolute;
  top: calc(100% + 27px);
  right: 0;
  z-index: 30;
  width: min(440px, calc(100vw - 32px));
  display: grid;
  gap: 10px;
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--ink);
}

/* The link sits in a command box with its copy key, as `ardana pull` does on the landing. */
.popover-row {
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 40px;
  padding: 0 4px 0 14px;
  border-radius: var(--radius);
  background: var(--code-bg);
}

.popover-row:has(.field-input:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}

/* The link is read only, a thing to copy: the box is the landing's command box, without an input's ring. */
.popover-row .field-input {
  flex: 1;
  min-width: 0;
  min-height: 0;
  padding: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.popover-row .field-input:focus-visible {
  outline: none;
}

/* The copy key's tooltip opens upwards here, over the label, so it never covers the note under the link. */
.popover .tip-below::after {
  top: auto;
  bottom: 100%;
}

@media (max-width: 720px) {
  /* The stale state is carried by each question's tag; a truncated stub in the top bar says nothing. */
  .changed .tag {
    display: none;
  }

  /* The lockup names the page on a phone, and leads home. */
  .topbar-nav {
    display: none;
  }

  .topbar-actions {
    margin-left: auto;
  }

  /* No empty slot for the stale tag, and a narrower Run, so "Running" and its caret fit the bar at 390px. */
  .changed {
    display: none;
  }

  .topbar .run-key {
    padding: 0 14px;
  }

  .topbar .logo > svg {
    height: 22px;
  }

  /* The Share popover hangs 8px under the bar, however many rows the bar takes. */
  .popover {
    position: fixed;
    top: calc(var(--topbar-height) + 8px);
    right: 16px;
    left: 16px;
    width: auto;
  }

  /* The bytes take their lines, the bar fills the next row with Stop at its end, at any text size. */
  .banner {
    flex-wrap: wrap;
  }

  .banner-track:has(.banner-progress) {
    flex: 1 1 100%;
  }

  .banner-track .banner-progress {
    flex: 1 1 0;
  }
}

/* The smallest phones: the lockup at 18px (above the kit's 80px minimum width), tighter gaps and Share as its glyph keep
   the bar on one line from 320px, at rest and while running (WCAG 1.4.10); from 390px the bar holds its 22px lockup. */
@media (max-width: 389px) {
  .topbar {
    column-gap: var(--space-2);
  }

  .topbar-logo {
    margin-right: 0;
  }

  .topbar .logo > svg {
    height: 18px;
  }

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

  .topbar .share .button {
    width: 32px;
    padding: 0;
  }

  .share-icon {
    display: block;
  }

  .share-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* ---- The drawer: below 960px the sidebar slides in over the page, on a scrim. ---- */

.scrim {
  display: none;
}

@media (max-width: 960px) {
  .shell,
  .shell.collapsed {
    grid-template-columns: minmax(0, 1fr);
  }

  .sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 60;
    width: min(var(--sidebar), 85vw);
    height: 100vh;
    height: 100dvh;
    transform: translateX(-100%);
    visibility: hidden;
    transition:
      transform var(--normal) var(--ease-out),
      visibility 0s var(--normal);
  }

  .shell.drawer-open .sidebar {
    transform: none;
    visibility: visible;
    transition:
      transform var(--normal) var(--ease-out),
      visibility 0s;
  }

  .shell.collapsed .sidebar {
    visibility: hidden;
  }

  .shell.drawer-open.collapsed .sidebar {
    visibility: visible;
  }

  .workspace .button-icon {
    opacity: 1;
  }

  .shell .topbar .opener,
  .shell.collapsed .topbar .opener,
  .shell .topbar .topbar-logo,
  .shell.collapsed .topbar .topbar-logo {
    display: inline-flex;
  }

  .scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 55;
    border: 0;
    padding: 0;
    background: var(--scrim);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--normal) var(--ease-out);
  }

  .shell.drawer-open .scrim {
    opacity: 1;
    pointer-events: auto;
  }
}

/* Under a coarse pointer the rows and the share link's box are 44px tall, and the banner's actions (Stop, "Show the
   command") reach 44px past their words within a 44px banner (WCAG 2.5.5); see controls.css. */
@media (pointer: coarse) {
  .logo,
  .topbar-nav a {
    position: relative;
  }

  .logo::before,
  .topbar-nav a::before {
    content: "";
    position: absolute;
    inset: min(0px, (100% - 44px) / 2);
  }

  .row,
  .popover-row,
  .banner {
    min-height: 44px;
  }

  /* The share link takes the whole height of its box. */
  .popover-row .field-input {
    align-self: stretch;
  }

  .banner-action {
    position: relative;
  }

  .banner-action::before {
    content: "";
    position: absolute;
    inset: min(0px, (100% - 44px) / 2);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar,
  .shell.drawer-open .sidebar,
  .scrim,
  .row,
  .topbar-nav a,
  .row .icon-back,
  .banner-action .icon,
  .workspace .button-icon,
  .skip-link {
    transition: none;
  }

  .row:hover .icon-back {
    transform: scaleX(-1);
  }

  .banner-action:hover .icon {
    transform: none;
  }
}

@media (forced-colors: active) {
  .sidebar {
    border-right: 1px solid CanvasText;
  }

  .workspace,
  .topbar,
  .banner {
    border-bottom: 1px solid CanvasText;
  }

  .popover-row {
    border: 1px solid CanvasText;
  }

  .banner-progress {
    border: 1px solid CanvasText;
  }

  .banner-progress::-webkit-progress-value {
    background: Highlight;
  }

  .banner-progress::-moz-progress-bar {
    background: Highlight;
  }
}
