/*
 * The Output Screen: what a Model's Output has on disk (docs/adr/0003).
 *
 * Breakpoints follow the Shell's (mobile <768, tablet 768–1279, desktop
 * ≥1280 — shell.css), plus one extra tier at 1280 for how many Illustrasi
 * Index Thumbnails the carousel shows at once: 2 on mobile, 3 on tablet, 5 on
 * desktop, read off the Figma frames (node 40:2).
 */

.output {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);

  /* One thumbnail's height, shared by the carousel and the grid. Named because
     the Detail cap below has to count it. */
  --output-thumb-height: 161px;

  /* Everything above the Detail grid, so the cap can be "whatever viewport is
     left". Spelled out term by term rather than as one number: each line is a
     real box on this Screen, so a change to any of them stays honest here. */
  --output-detail-chrome: calc(
    var(--navbar-height) /* sticky navbar */ + var(--space-5) +
      var(--space-20) /* .page padding-block */ + 40px /* the top bar */ +
      var(--space-4) /* gap below it */ + var(--leading-base) /* model name */ +
      var(--space-4) /* gap below it */ + var(--space-5) + var(--space-5)
      /* the card's own padding-block */ + var(--leading-base) +
      var(--space-5) + var(--output-thumb-height) /* Illustrasi Index section */ +
      var(--space-5) /* gap down to Detail */ + var(--leading-base) +
      var(--space-5) /* Detail's header and the gap under it */
  );

  /* What Figma gives the Detail grid at both desktop and tablet (its section is
     495 tall with a 44 header). Two full rows and most of a third — the part
     row is what says there is more below. Kept as the floor so a short viewport
     never squeezes the grid below the height the design was drawn at. */
  --output-detail-min: 451px;

  /* Raw fills sampled off the design's two file cards, not Figma variables —
     the file declares none for them, the same way --input-bg has none. One tint
     per file type is the whole of what tells the two cards apart at a glance;
     the strip over them is the same white for both (node 40:516). */
  --file-xlsx-tint: #cbebd3;
  --file-sql-tint: #a3ceff;
  --file-name-strip: rgb(255 255 255 / 70%);
}

/* -- Top bar and title -------------------------------------------------- */

.output__topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

/* The arrow and "Kembali ke Home" are two buttons, 10 apart (node 40:588). */
.output__back-group {
  display: flex;
  align-items: center;
  gap: var(--space-2-5);
}

/* Both top-bar glyphs are drawn at 20 (nodes 40:590 and 40:600), not the 16 the
   shared .icon carries or the 24 a .btn--icon defaults to. Scoped here so the
   Screens sharing those classes keep their own sizes. */
.output__topbar .btn svg {
  width: 20px;
  height: 20px;
  flex: none;
}

/* At mobile the design drops this button's label and squares it off to 46
   (node 40:820), while "Kembali ke Home" keeps its text. */
@media (max-width: 767px) {
  .output__download-label {
    display: none;
  }

  .output__topbar .btn--primary {
    padding-inline: 13px;
  }
}

/* Not in the Figma frame — see the comment beside it in index.html. Kept
   understated so it reads as orientation, not a section of its own. */
.output__title {
  margin: 0;
  font-size: var(--text-base);
  line-height: var(--leading-base);
  font-weight: var(--weight-medium);
  color: var(--muted-foreground);
}

.output__empty {
  margin: 0;
  padding: var(--space-10) var(--space-5);
  background: var(--card);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-3xl);
  color: var(--muted-foreground);
  text-align: center;
}

/* The one card on this Screen (node 40:489). The three sections inside it are
   plain flow, not cards of their own — the design draws a single border around
   the lot. */
.output__content {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-5);
  background: var(--card);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-3xl);
}

/* -- Section shell -------------------------------------------------------- */

.output-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}

/* The shared header insets itself by 20, which is right for a card that owns
   its padding. These sections do not — the card above does — so left as-is the
   titles would sit 20 past the thumbnails they label, which is not what the
   design does (both are at x=20 from the card edge). */
.output-section .card__header {
  padding-inline: 0;
}

.output-section__empty {
  margin: 0;
  padding: var(--space-6) 0;
  color: var(--muted-foreground);
  text-align: center;
}

/* Illustrasi Index and Data XLSX & SQL stack on mobile and sit side by side
   from tablet up. The files column keeps the same 300 at both widths;
   Illustrasi Index takes the rest.

   The 40 gap is what the design measures: Figma draws the two as 940 + 320
   containers 20 apart, and only the Illustrasi Index side insets its content by
   a further 20 (node 40:516 starts its own at x=0). Only the content is
   reproduced here — the card above supplies the outer inset — so those two 20s
   add up into one gap. It is what makes the thumbnails land on their drawn
   widths: 167.2 at desktop, 114 at tablet. */
.output__top-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

@media (min-width: 768px) {
  .output__top-row {
    flex-direction: row;
    align-items: stretch;
    gap: calc(var(--space-5) * 2);
  }

  .output__top-row > .output-section:first-child {
    flex: 1;
    min-width: 0;
  }

  /* 300 = two 140 cards 20 apart. Widening it by the 20 the gap gave up leaves
     Illustrasi Index on exactly the width it had, so no thumbnail moves. */
  .output__top-row > .output-section:last-child {
    flex: 0 0 300px;
  }
}

/* -- Thumbnails ------------------------------------------------------------ */
/* Shared by the carousel and the grid: a fixed-height frame with the image
   contained inside it, never cropped — these are technical line art, and
   cropping risks cutting off a part number. */

.output-thumb {
  display: block;
  height: var(--output-thumb-height);
  padding: 0;
  background: var(--muted);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-input);
  cursor: pointer;
  overflow: hidden;
}

.output-thumb:focus-visible {
  outline: 2px solid var(--foreground);
  outline-offset: 2px;
}

.output-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* -- Illustrasi Index carousel ---------------------------------------------- */

/* How many Thumbnails are on screen at once: 2 on mobile, 3 on tablet, 5 on
   desktop, per the three Figma frames. Declared as a property rather than
   baked into the flex-basis because output.js needs the same number — it
   builds exactly that many Thumbnails per step — and two places counting
   windows differently is how a carousel ends up with a blank slot. */
.output-carousel {
  position: relative;
  --output-carousel-visible: 2;
}

@media (min-width: 768px) {
  .output-carousel {
    --output-carousel-visible: 3;
  }
}

@media (min-width: 1280px) {
  .output-carousel {
    --output-carousel-visible: 5;
  }
}

.output-carousel__viewport {
  overflow: hidden;
}

/* Holds only the Thumbnails currently on screen — the carousel steps by
   redrawing this, not by sliding a track of all 133. */
.output-carousel__track {
  display: flex;
  gap: var(--space-4);
}

.output-carousel__track .output-thumb {
  flex: 0 0
    calc(
      (100% - (var(--output-carousel-visible) - 1) * var(--space-4)) /
        var(--output-carousel-visible)
    );
}

/* Centred on the thumbnail row's own left and right edges — half over the
   outermost thumbnail, half over the card's padding. Measured off the design's
   render: the row spans 20–919 and the circles sit at 6–33 and 906–933, so
   each is centred exactly on an edge rather than inset from it. */
.output-carousel__arrow {
  position: absolute;
  top: 50%;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  background: var(--color-white);
  border: var(--border-width) solid var(--border);
  border-radius: 999px;
  color: var(--foreground);
  cursor: pointer;
}

.output-carousel__arrow svg {
  width: 16px;
  height: 16px;
}

.output-carousel__arrow--prev {
  left: 0;
  transform: translate(-50%, -50%);
}

.output-carousel__arrow--next {
  right: 0;
  transform: translate(50%, -50%);
}

.output-carousel__arrow:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.output-carousel__arrow:focus-visible {
  outline: 2px solid var(--foreground);
  outline-offset: 2px;
}

/* -- Data XLSX & SQL cards ------------------------------------------------ */

/* The two cards, 20 apart and equal (node 229:2629), which at the column's 300
   is the 140 each the design draws. Equal rather than sized to their contents
   because neither file is the more important one, and a file name is not a
   width worth laying out to. */
.output-files {
  display: flex;
  gap: var(--space-5);
}

/* One slot per file, holding either the card or the line saying the run did not
   produce it. Each keeps its half whichever it is showing, so a missing file
   leaves a gap where it would have been rather than letting the other card
   spread across the column — which would read as "there is one file here". */
.output-files__slot {
  flex: 1;
  min-width: 0;
}

/* Exactly as tall as the Thumbnail row beside it, so the two columns end on
   the same line — which is what the design draws and what makes the buttons
   below sit level with the bottom of the Illustrasi Index row. The preview
   takes whatever the 40 button and the gap leave it, which is the 105 Figma
   gives it. */
.output-file {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  height: var(--output-thumb-height);
}

.output-file__preview {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-xl);
  overflow: hidden;
}

.output-file__preview--xlsx {
  background: var(--file-xlsx-tint);
}

.output-file__preview--sql {
  background: var(--file-sql-tint);
}

/* Centred on the whole preview, which is taller than the glyphs' 64 — so a foot
   runs into the name strip claiming the bottom 32. The strip sits above it (see
   its z-index) but is translucent, so the glyph carries on through it while the
   file name stays legible, as the design draws both cards.

   The two glyphs are not the same shape and so are not sized together: the
   spreadsheet is a 46.64 x 64 page, the database a 64 square. */
.output-file__icon {
  flex: none;
  height: 64px;
}

.output-file__icon--xlsx {
  width: 47px;
}

.output-file__icon--sql {
  width: 64px;
}

.output-file__name {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  /* Above the glyph. Stated rather than left to paint order, which would put
     the glyph on top the moment anything gives it a position of its own. */
  z-index: 1;
  margin: 0;
  padding-inline: var(--space-3);
  background: var(--file-name-strip);
  font-size: var(--text-sm);
  /* Doubles as the strip's 32 height. */
  line-height: 32px;
  font-weight: var(--weight-medium);
  color: var(--foreground);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* -- Detail grid --------------------------------------------------------- */

.output-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
}

@media (min-width: 768px) {
  .output-grid {
    grid-template-columns: repeat(5, 1fr);
  }

  /* The Detail grid scrolls inside the card rather than growing the page, as
     both the desktop and tablet frames draw it. A cap, not a fixed height: a
     Model with only a handful of Detail images still gets a short card instead
     of 451px of white space. Below 768 there is no cap at all — the mobile
     frame draws the grid full height, and a scroll region inside a scrolling
     page is worse on a touch screen than a long page is. */
  .output-section--detail .output-grid {
    max-height: max(
      var(--output-detail-min),
      calc(100vh - var(--output-detail-chrome))
    );
    overflow-y: auto;
    overscroll-behavior: contain;
    /* Deliberately no scrollbar-gutter: whether this grid scrolls is settled
       for a given Model before it is drawn, so there is no mid-view shift to
       reserve against — and on a platform with overlay scrollbars a reserved
       gutter would narrow every Thumbnail for nothing. */
  }
}

/* -- Lightbox ------------------------------------------------------------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-10);
  background: rgb(0 0 0 / 85%);
}

.lightbox__image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: var(--radius-input);
}

.lightbox__close,
.lightbox__nav {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: rgb(255 255 255 / 12%);
  border: none;
  border-radius: 999px;
  color: var(--color-white);
  cursor: pointer;
}

.lightbox__close:hover,
.lightbox__nav:hover {
  background: rgb(255 255 255 / 24%);
}

.lightbox__close:focus-visible,
.lightbox__nav:focus-visible {
  outline: 2px solid var(--color-white);
  outline-offset: 2px;
}

.lightbox__close {
  top: var(--space-5);
  right: var(--space-5);
  width: 40px;
  height: 40px;
}

.lightbox__close svg {
  width: 20px;
  height: 20px;
}

.lightbox__nav {
  top: 50%;
  width: 48px;
  height: 48px;
  transform: translateY(-50%);
}

.lightbox__nav svg {
  width: 20px;
  height: 20px;
}

.lightbox__nav--prev {
  left: var(--space-5);
}

.lightbox__nav--next {
  right: var(--space-5);
}

.lightbox__nav:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}
