/* The generation workspace (WORKSPACE.md Phase C): control rail plus
   canvas on desktop, stacked on mobile. Rail cards reuse the upload-card
   and style-picker-card surfaces; this file only owns the layout, the
   style modal, and the board chrome. */

.workspace {
  display: grid;
  gap: var(--space-5);
  align-items: start;
}

.workspace-rail {
  display: grid;
  gap: var(--space-4);
}

.rail-scroll {
  display: grid;
  gap: var(--space-4);
  align-content: start;
}

.rail-pinned {
  display: grid;
  gap: var(--space-2);
}

@media (min-width: 1024px) {
  .workspace {
    grid-template-columns: 360px minmax(0, 1fr);
  }

  /* Fal-style rail (owner call 2026-07-18): the rail pins to the
     viewport, its controls scroll internally, and the pinned footer
     keeps the render button in reach no matter how long the canvas
     gets. The page scrollbar stays the canvas scrollbar. These rules
     must come after the base .workspace-rail block: they override its
     grid display at desktop widths.

     Two corrections (2026-07-24). The sticky offset clears the site
     header: at top: space-3 the rail's first card slid under the
     header's blur once you scrolled. And the height subtracts the
     header plus the greeting row, because at rest the rail starts
     below both; sizing against the bare viewport pushed .rail-pinned,
     and with it the render button, under the fold on arrival. Costs
     the rail --dash-chrome of scroll depth once scrolled past the
     greeting, which is the right trade for a CTA that is never
     off-screen. svh, not vh, so mobile browser chrome cannot do the
     same thing again. */
  .workspace-rail {
    position: sticky;
    top: calc(var(--header-h) + var(--space-3));
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    max-height: calc(100svh - var(--header-h) - var(--dash-chrome) - var(--space-5));
  }

  .rail-scroll {
    overflow-y: auto;
    min-height: 0;
    padding-right: var(--space-2);
    /* The overflow cut the quality cards clean in half with nothing to
       say more was below. A short static fade reads as a scroll edge.
       Deliberately not a scroll-driven animation that lifts at the end:
       animation-timeline is Chromium-only, and the fallback there is a
       permanently dimmed final control in Safari and Firefox. Static
       costs one faded hairline at the very bottom of the scroll and is
       the same everywhere. */
    mask-image: linear-gradient(to bottom, #000 calc(100% - var(--space-4)), transparent 100%);
    /* The rail's own scrollbar, quieted: the default macOS bar rendered
       as a hard grey rule between rail and canvas and read as a page
       artifact rather than as the rail's own overflow. */
    scrollbar-width: thin;
    scrollbar-color: var(--line) transparent;
  }

  .rail-scroll::-webkit-scrollbar {
    width: 6px;
  }

  .rail-scroll::-webkit-scrollbar-track {
    background: transparent;
  }

  .rail-scroll::-webkit-scrollbar-thumb {
    background: var(--line);
    border-radius: 3px;
  }

  .rail-scroll:hover::-webkit-scrollbar-thumb {
    background: var(--ink-soft);
  }

  /* The rail's vertical budget belongs to the controls that gate a
     render, not to the photo you set once: rail cards run tighter than
     the page-level card they share a class with. */
  .workspace-rail .upload-card,
  .workspace-rail .style-picker-card {
    padding: var(--space-4);
    margin-top: 0;
  }

  .rail-pinned {
    padding-top: 0;
  }

  /* The thumb is sized by .upload-current now (auth.css): a 5.5rem
     square beside the Replace button, rather than a full-width preview
     capped at 9rem. Overriding it here as well only reopened a
     specificity tie between two files. */
}

.workspace-canvas {
  display: grid;
  gap: var(--space-4);
}

/* Picked styles in the rail (2026-09-03): the photo card's own
   language, a small tile beside the name, and the Change button on the
   same row; the row wraps when a board fills up. */

.board-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.board-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.board-chips:empty {
  display: none;
}

.board-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.25rem 0.7rem 0.25rem 0.25rem;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
  background: var(--paper-card);
  border: 1.5px solid var(--line);
  border-radius: var(--radius-md);
}

.board-chip img {
  display: block;
  width: 2.25rem;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-sm);
}

.board-count {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-soft);
}

.board-note {
  font-size: var(--text-sm);
  color: var(--ink-soft);
}

/* The free-tier board upsell tile: honest tease, no fake locked slots */

.board-upsell {
  border: 1px dashed var(--ink-soft);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  font-size: var(--text-sm);
  color: var(--ink-soft);
}

.board-upsell a {
  color: var(--accent);
}

/* The style picker modal */

.style-modal {
  width: min(64rem, calc(100vw - 2rem));
  max-height: 88vh;
  /* The global `* { margin: 0 }` reset kills the UA rule that centers
     native dialogs; margin: auto restores it (the lightbox carried this
     line since generations.css, the picker opened top-left until the
     2026-09-02 critique). */
  margin: auto;
  border: var(--border-hard);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  background: var(--paper);
}

.style-modal::backdrop {
  background: rgba(16, 16, 16, 0.55);
}

.style-modal-head {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  margin-bottom: var(--space-3);
}

.style-modal-head input[type="search"] {
  flex: 1;
  font: inherit;
  padding: 0.5em 0.9em;
  border: var(--border-hard);
  border-radius: var(--radius-pill);
  background: var(--paper-card);
}

/* The search filter sets [hidden]; the grid's display rule on
   .style-option would beat the UA stylesheet without this. */
.style-modal .style-option[hidden] {
  display: none;
}

.style-modal .style-picker-grid {
  max-height: 62vh;
  overflow-y: auto;
  padding-right: var(--space-1);
}

.style-modal-foot {
  display: flex;
  justify-content: flex-end;
  margin-top: var(--space-3);
}

/* Rail credit summary under the render button */

.rail-credits {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-soft);
}

/* Hint under the disabled render button until a pick arms it */

.rail-hint {
  font-size: var(--text-xs);
  color: var(--ink-soft);
}

/* Header usage ring (all authenticated pages, USAGE.md decision 2): a
   circle that fills as the period's allowance is used, the percent in
   mono beside it. The arc's dash length is the percent itself (the
   markup sets pathLength 100 and the dash as a presentation attribute,
   since the CSP blocks inline styles); the rotation starts it at
   twelve o'clock; the one-time keyframe draws it in on load, from
   empty to that value (an animation's missing keyframe is the
   element's own value, so CSS must not set the dash itself). Past 80 percent the arc turns ink; at the
   cap the label reads Limit. On phones the pill and the percent go and
   the ring stands alone, narrower than the two-digit count it
   replaced. It links to /designs, where the count is spelled out. */

.usage-wrap {
  position: relative;
  display: inline-flex;
}

.usage-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  background: transparent;
  color: inherit;
  cursor: pointer;
  border: 1px solid var(--ink);
  border-radius: var(--radius-pill);
  padding: 0.35em 0.75em 0.35em 0.55em;
  text-decoration: none;
  color: var(--ink);
  white-space: nowrap;
  transition: background-color 150ms ease;
}

.usage-chip:hover {
  background: var(--paper-deep);
}

.usage-ring {
  width: 1.3em;
  height: 1.3em;
  flex: none;
  transform: rotate(-90deg);
}

.usage-ring circle {
  fill: none;
  stroke-width: 3.2;
}

.usage-ring-track {
  stroke: var(--line);
}

.usage-ring-arc {
  stroke: var(--accent);
  animation: usage-ring-in 700ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

@keyframes usage-ring-in {
  from {
    stroke-dasharray: 0 100;
  }
}

/* The ring's card (2026-09-09): the count, the refresh date, the
   designs link. Opened by the tap (usage-tip controller toggles
   is-open), by hover and focus on pointer devices. A paper card with
   the hard border and offset shadow so it reads on the dark hero too. */
.usage-tip {
  display: none;
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 30;
  min-width: 15rem;
  padding: var(--space-3) var(--space-4);
  background: var(--paper-card);
  color: var(--ink);
  border: var(--border-hard);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-soft);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: 1.4;
  text-align: left;
  gap: 0.3rem;
}

.usage-wrap.is-open .usage-tip {
  display: grid;
}

@media (hover: hover) {
  .usage-wrap:hover .usage-tip,
  .usage-wrap:focus-within .usage-tip {
    display: grid;
  }
}

.usage-tip strong {
  font-weight: 600;
}

.usage-tip a {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--accent);
  margin-top: 0.2rem;
}

.usage-chip.is-warn .usage-ring-arc,
.usage-chip.is-full .usage-ring-arc {
  stroke: var(--ink);
}

.usage-chip.is-full .usage-percent {
  font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
  .usage-ring-arc {
    animation: none;
  }
}

@media (max-width: 479px) {
  /* The card hangs from the header's action row, not the ring, so it
     never runs off the left edge of a phone. */
  .usage-wrap {
    position: static;
  }

  .header-actions {
    position: relative;
  }

  .usage-chip {
    border: 0;
    padding: 0;
    gap: 0;
  }

  .usage-percent {
    display: none;
  }

  .usage-ring {
    width: 1.65em;
    height: 1.65em;
  }
}

/* Empty-state worked example in the canvas */

.canvas-example {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
}

.canvas-example figure {
  margin: 0;
}

.canvas-example img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-md);
  display: block;
}

.canvas-example figcaption {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-soft);
  margin-top: var(--space-1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* Render pages (Phase D) */

.render-meta {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.render-ba {
  margin-block: var(--space-4);
}

.render-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  margin-block: var(--space-3);
}

.render-board-strip {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: var(--space-2);
}

.render-board-thumb {
  display: grid;
  gap: var(--space-1);
  text-decoration: none;
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
}

.render-board-thumb img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-md);
  display: block;
}

.gallery-fresh {
  margin-bottom: var(--space-6);
}

/* Premium style locks in the picker (Phase E) */

.style-option.is-locked {
  text-decoration: none;
  color: inherit;
}

.style-option.is-locked img {
  opacity: 0.55;
}

.style-lock {
  font-style: normal;
  font-family: var(--font-mono);
  font-size: 0.7em;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  background: var(--ink);
  color: var(--paper);
  padding: 0.15em 0.5em;
  border-radius: var(--radius-pill);
  margin-left: 0.4em;
}

/* The search filter also applies to locked cards */
.style-modal .style-option.is-locked[hidden] {
  display: none;
}

/* R3 phase 2: the home tool grid, feature-card stack, per-tool bar,
   and the designs history grid. */

.tools-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
  gap: var(--space-3);
  margin: var(--space-3) 0 var(--space-6);
}

.tool-tile {
  display: grid;
  gap: 2px;
  padding: var(--space-3) var(--space-4);
  background: var(--paper-card);
  border: var(--border-hard);
  border-radius: var(--radius-md);
  text-decoration: none;
  color: var(--ink);
  box-shadow: var(--shadow-soft);
  transition: transform 0.15s ease-out, box-shadow 0.15s ease-out;
}

.tool-tile:hover {
  transform: translate(-2px, -2px);
  box-shadow: var(--shadow-deep);
}

.tool-tile:hover .tool-tile-label {
  color: var(--accent);
}

.tool-tile-label {
  font-weight: 600;
}

.tool-tile-hint {
  font-size: var(--text-xs);
  color: var(--ink-soft);
}

.tool-features {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(21rem, 100%), 1fr));
  gap: var(--space-4);
}

.tool-feature {
  display: grid;
  text-decoration: none;
  color: var(--ink);
  background: var(--paper-card);
  border: var(--border-hard);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-soft);
  transition: transform 0.15s ease-out, box-shadow 0.15s ease-out;
}

.tool-feature:hover {
  transform: translate(-2px, -2px);
  box-shadow: var(--shadow-deep);
}

.tool-feature-video {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
  background: var(--paper-deep);
}

.tool-feature-copy {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
}

.tool-feature-label {
  font-weight: 600;
}

.tool-feature-hint {
  grid-column: 1;
  font-size: var(--text-xs);
  color: var(--ink-soft);
}

.tool-feature-cta {
  grid-row: 1 / span 2;
  grid-column: 2;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--accent);
  white-space: nowrap;
}

.tool-bar-back a {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-soft);
}

/* The tool bar stacks its lines, so the inline separator dot dash-plan
   carries on the home greeting row would orphan here. */
.tool-bar .dash-plan::before {
  content: none;
}

@media (prefers-reduced-motion: reduce) {
  .tool-tile,
  .tool-feature {
    transition: none;
  }

  .tool-tile:hover,
  .tool-feature:hover {
    transform: none;
  }
}

/* The narrowest phones keep the header to chip + Home (the 2026-07-25
   overflow lesson); the home grid's My designs button takes over there
   and only there, so exactly one Designs entry exists at any width. */
@media (max-width: 480px) {
  .header-nav-designs {
    display: none;
  }
}

@media (min-width: 481px) {
  .dash-designs-link {
    display: none;
  }
}

.designs-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(19rem, 100%), 1fr));
  gap: var(--space-4);
  align-items: start;
  /* The co-applied .generations caps the workspace canvas at 34rem
     (right beside a rail); the history page is full width, and this
     grid never rendered more than one column until 2026-09-02. */
  max-width: none;
}

/* Section labels on the home grid are real headings (screen readers
   skip by them); the kicker look is unchanged. */
.dash-page h2.kicker {
  line-height: inherit;
  text-wrap: auto;
}

/* The All Tools icon set (2026-08-10): thin-line SVGs, ink by default,
   accent with the tile hover. */

.tool-icon {
  width: 1.5rem;
  height: 1.5rem;
  margin-bottom: var(--space-1);
}

.tool-tile:hover .tool-icon {
  color: var(--accent);
}

.tool-bar-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.tool-bar-title .tool-icon {
  width: 1.75rem;
  height: 1.75rem;
  margin-bottom: 0;
  flex-shrink: 0;
}

/* Pager under the designs grid (2026-09-02, 48 per page): newer left,
   older right, the page count between; a missing side keeps its slot so
   the other never jumps. */
.designs-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

.designs-pager-page {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-soft);
}

/* First run (REVEAL.md decision 4): Interior Design wears a Start here
   mark until the account has made its design; the tile keeps its
   geometry, the mark sits in the corner in the grid's mono voice. */

.tool-tile {
  position: relative;
}

.tool-tile.is-start {
  border-color: var(--accent);
  box-shadow: 4px 4px 0 rgba(43, 60, 255, 0.35);
}

.tool-tile-badge {
  position: absolute;
  top: -0.6rem;
  right: var(--space-3);
  font-family: var(--font-mono);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  background: var(--accent);
  color: var(--paper-card);
  padding: 0.15em 0.6em;
}

.dash-first-run {
  max-width: 40rem;
}
