/* The public surface (stage 3, S3-4): a published project's page, a maker's page, /explore.

   Shared components are NOT restyled here — `.markdown`, `.repo-card`, `.log-timeline`,
   `.tag-chip`, `.panel`, `.table` and `.thumb` come from components.css and pages/projects.css and
   look the same to a visitor as to the owner, which is the point of reusing the partials at all
   (§14m rule 3: a component selector is defined once). What follows is this surface's OWN classes,
   plus the container qualifications a component needs inside them. */
@layer pages {
  /* The anonymous layout branch defaults `main` to `.auth-main` (a 440px column for the sign-in
     card). A public page opts out of that with `content_for :container_class, "public-main"`;
     `main.container`'s own max-width then applies, so this rule only has to exist, not to do
     much. */
  .public-main { max-width: 1360px; }

  .public-head .public-byline { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    margin: 4px 0 0; font-size: 13px; color: var(--fg-muted); }
  .public-head .public-byline a { color: var(--fg); }

  .public-section { margin: 14px 0 4px; font-size: 13px; font-weight: 600; color: var(--fg-muted); }

  /* THE BUNDLE BUTTON AND ITS STATUS (stage 3, S3-6). A flex row that WRAPS, because the status is
     a whole sentence — "Fetching 7 of 30: models/bracket-v3-final.stl", or the failure line naming
     a file — and at 375px it has to go under the button rather than push the page sideways
     (§14m rule 11; test/system/shell_test.rb's sweep is what would say otherwise).
     `overflow-wrap: anywhere` for the same reason a long file NAME needs it in the tables. */
  /* The div carries `page-actions` too, which is where the flex/wrap/align/gap come from — this
     rule held a verbatim copy of all four until 2026-09-10. Only the margin is the bundle's own. */
  .bundle { margin-top: 8px; }
  .bundle .muted { font-size: 12px; overflow-wrap: anywhere; }

  /* 40px, matching `table.files .thumb` — the same row height the owner's file list has. */
  .public-files .col-thumb .thumb { width: 40px; height: 40px; flex: 0 0 40px; }
  .public-files .col-thumb { width: 48px; }
  .public-files .col-dl { width: 1%; white-space: nowrap; text-align: right; }

  /* A FOLDER PANEL'S TILE GRID (2026-09-08, folder panels). The page's own grid; the CARD inside
     each cell is the shared component (`.grid-card`, `.grid-name` in components.css) and the box
     is the shared `.thumb`, so this sheet declares only the container and the one size the
     container implies — §14m rule 3, the same shape `.public-photos` two lines down already has.
     140px matches the owner's own `.files-grid`, so the same folder reads the same on both pages. */
  .public-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 16px; }
  .public-tiles .thumb { width: 100%; height: 140px; }

  .public-photos { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 8px; }
  .public-photos .photo-cell .thumb { width: 100%; height: 120px; }
  .entry-photos .photo-cell .thumb { width: 96px; height: 96px; }

  .project-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 16px; margin-top: 12px; }
  .project-card-grid .card-title { font-size: 14px; margin: 0; }
  .project-card-grid .card-blurb { font-size: 12px; margin: 0; }
  .project-card-grid .card-time { font: 11px/1.4 var(--font-mono); }
  /* The pager sits BELOW the grid here, where files/index.html.erb puts it above its list, so the
     component's bottom margin is the wrong side: a qualified override (design-system.md rule 3),
     not a second component. */
  .public-main .pager { margin: 16px 0 0; }
  /* THE COVER SLOT (stage 4, S4-5). `width: 100%` IS THE WHOLE RULE, AND IT IS NOT DECORATION:
     `.project-card` is `align-items: center` (pages/projects.css), which sizes a block child to
     shrink-to-fit in the cross axis — so `.project-card .thumb`'s own `width: 100%` would resolve
     against the anchor's content width and starve the cover down to the icon, exactly the trap
     that sheet's `.project-tile` comment already records for the private card. Nothing else is
     needed: the cell's size comes from `.project-card .thumb` and the placeholder icon's from
     `.project-card .project-thumb-empty .rail-icon`, both in pages/projects.css and both correct here —
     a second copy is what §14m rule 3 exists to stop. */
  .project-card-grid .card-cover { display: block; width: 100%; }

  .explore-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 4px; }
  .explore-chips .tag-chip.active { border-color: var(--fg); background: var(--fg); color: var(--surface); }

  /* COLUMN DROPS: Size is the least useful cell to a visitor on a phone, the thumbnail the next
     least; Name and Download survive at every width. READABILITY, NOT OVERFLOW SAFETY, and the
     distinction is measured rather than argued — deleting both blocks leaves test/system/
     shell_test.rb's phone sweep GREEN, because the table's min-content already fits 375px. The
     same result pages/files.css's own drops have, recorded in that sweep's header. */
  /* RELEASES (stage 3, S3-5) ARE STYLED IN pages/projects.css AND DELIBERATELY NOT COPIED HERE.
     The layout links every page sheet on every page (application.html.erb; css_hygiene_test.rb
     pins the order), so a `pages/` file scopes rules by NAME, not by which page loads it -- and
     `.releases-panel` is the same markup on both pages, rendered by two partials that share
     `Maker::ReleaseFile#state_against` for exactly this reason. A second identical block here
     would be a copy that has to be kept in step, which is what the panel's one shared rule
     (`.badge.changed`, in components.css) already exists to avoid. */

  @media (max-width: 719px) {
    .public-files .col-size { display: none; }
  }
  @media (max-width: 479px) {
    .public-files .col-thumb { display: none; }
  }

  /* THE COMPOSE GENERATOR (/install/compose, 2026-10-21). The form beside its file on a wide screen,
     the file under the form on a narrow one. The YAML scrolls inside its own box, never the page
     (design-system.md rule 11), and it sticks beside the form while the form scrolls. The groups are
     `.panel`s and the inputs `.field`s from components.css; what follows is this page's own layout.
     Tokens only, so both themes follow. */
  .compose-layout { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--space-5); align-items: start; }
  /* Every block in a group ends with 12px of its own margin, so a 4px bottom padding makes 16 below
     whichever block is last -- the panel's 16 on the other sides -- however the folder, share and
     guest switches change which one that is. A closed <details> has only its summary. */
  .compose-group { min-width: 0; margin: 0 0 var(--space-4); padding-bottom: var(--space-1); }
  .compose-group .field { margin-bottom: var(--space-3); }
  details.compose-group:not([open]) { padding-bottom: var(--space-4); }
  /* A legend sits ON a fieldset's border unless it floats; floated, it is the panel's heading. */
  .compose-group > legend { float: left; width: 100%; padding: 0; margin: 0 0 var(--space-3); font-size: 15px; font-weight: 600; }
  .compose-group > legend + * { clear: both; }
  .compose-group > summary { cursor: pointer; font-size: 15px; font-weight: 600; }
  .compose-group[open] > summary { margin-bottom: var(--space-3); }
  .compose-choice { display: flex; flex-wrap: wrap; gap: 0 var(--space-4); margin: 0 0 var(--space-3); }
  .compose-choice .field-inline { margin-top: 0; }
  .compose-check { margin: 0 0 var(--space-1); }
  .compose-hint { max-width: 480px; margin: var(--space-1) 0 var(--space-3); font-size: 12px; color: var(--fg-muted); overflow-wrap: anywhere; }
  .field > .compose-hint { margin-bottom: 0; }
  .compose-hint code { font-size: 11px; line-height: 16px; }
  .compose-error { max-width: 480px; margin: var(--space-1) 0 0; font-size: 12px; color: var(--danger); }
  .compose-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--space-3); max-width: 480px; }
  .compose-output { position: sticky; top: var(--space-4); display: flex; flex-direction: column; max-height: calc(100vh - 2 * var(--space-4)); }
  .compose-output .panel-head h2 { font-size: 15px; }
  .compose-status { margin: 0 0 var(--space-3); font-size: 13px; }
  .compose-status:empty { margin: 0; }
  .compose-preview { flex: 1 1 auto; min-height: 0; margin: 0; padding: var(--space-3); overflow: auto; white-space: pre;
    font-size: 12px; line-height: 18px; background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-panel); }
  .compose-next { margin: var(--space-3) 0 0; font-size: 13px; }
  @media (max-width: 999px) {
    .compose-layout { grid-template-columns: minmax(0, 1fr); }
    .compose-output { position: static; max-height: none; }
    .compose-preview { max-height: 70vh; }
  }
}
