/* The UI kit over the app's shared pieces, drawn as shadcn/ui draws them: a screen's header
/* (layouts/shared/_page_header), pagination, the sidebar boxes and Save box (EditorHelper#postbox,
/* layouts/shared/_save_box), a screen of sections (_section_layout, _section_nav, as shadcn's
/* settings example), the KPI row (shared/_kpi_row, _kpi_tile, as the dashboard example's
/* section cards), a triage (shared/_attention, _attention_sheet), a list's filters
/* (shared/_filter_bar, _status_filter), sortable headers, tinted table rows, the command menu
/* (layouts/shared/_global_search) and a sortable row's moves. Reads only the kit's tokens. */
@layer ui {
  /* Page header: the title (text-2xl, semibold, tight), a muted line, the actions across. */

  .page-header {
    align-items: flex-end;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
    justify-content: space-between;
    margin-block-end: 0.5rem;
  }

  .page-header__text {
    display: grid;
    gap: 0.375rem;
    min-inline-size: 0;
  }

  .page-header__title {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
  }

  .page-header__icon {
    --icon-size: 1.5rem;

    color: var(--muted-foreground);
  }

  .page-header__description {
    color: var(--muted-foreground);
    font-size: var(--text-sm);
    margin: 0;
  }

  .page-header__back {
    margin-block-end: -0.5rem;

    a {
      align-items: center;
      display: inline-flex;
      gap: 0.375rem;
    }

    .icon {
      --icon-size: 0.875rem;
    }
  }

  .page-header__actions {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: flex-end;
    margin-inline-start: auto;

    details:has(> summary),
    details[open] > summary {
      margin-block-end: 0;
    }
  }

  /* A detail screen's facts, under its title: label value · label value. */
  .facts {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    font-size: var(--text-sm);
    gap: 0.25rem 0.75rem;
    margin: 0;

    dt {
      color: var(--muted-foreground);
    }

    dd {
      font-weight: 500;
      margin: 0;
    }
  }

  .facts__fact {
    align-items: baseline;
    display: flex;
    gap: 0.375rem;
  }

  /* Pagination: which rows these are, then the pages. */

  .pagination {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    justify-content: space-between;

    [aria-disabled="true"] {
      opacity: 0.5;
      pointer-events: none;
    }
  }

  .pagination__summary {
    color: var(--muted-foreground);
    font-size: var(--text-sm);
    margin: 0;
  }

  .pagination__pages {
    align-items: center;
    display: flex;
    gap: 0.25rem;
    list-style: none;
    margin: 0;
    padding: 0;
  }

  .pagination__page {
    min-inline-size: 2rem;
  }

  .pagination__gap {
    color: var(--muted-foreground);
    padding-inline: 0.375rem;
  }

  /* A sidebar box (EditorHelper#postbox): a small card whose header collapses it. */

  .postbox {
    gap: 0;
    padding-block: 0;
  }

  /* A Card header that is a <summary> (Collapsible): what it says, then at the end whatever
  /* sits beside the caret. Two columns whatever the header holds. */
  .ui-card__header.postbox__header {
    align-items: center;
    cursor: pointer;
    grid-template-columns: minmax(0, 1fr) auto;
    justify-content: space-between;
    list-style: none;
    padding-block: 0.875rem;
    user-select: none;

    &::-webkit-details-marker {
      display: none;
    }
  }

  .postbox[open] > .postbox__header {
    border-block-end: 1px solid var(--border);
  }

  .postbox__body {
    font-size: var(--text-sm);
  }

  .ui-card__content.postbox__body {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding-block: 1rem;
  }

  .postbox__toggle {
    --icon-size: 1rem;

    color: var(--muted-foreground);
    transition: rotate 100ms ease;

    .postbox:not([open]) > .postbox__header & {
      rotate: -90deg;
    }
  }

  /* The Save box: facts about the record, then the delete and the primary button in the card's
  /* footer. */
  .save-box__lines {
    color: var(--muted-foreground);
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1rem;

    strong {
      color: var(--foreground);
    }
  }

  .save-box__line {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 0.375rem;

    .icon {
      --icon-size: 1rem;
    }
  }

  .save-box__actions {
    align-items: center;
    background-color: var(--muted);
    border-end-end-radius: inherit;
    border-end-start-radius: inherit;
    display: flex;
    gap: 0.5rem;
    justify-content: space-between;
    padding: 0.75rem 1rem;
  }

  .save-box__actions--ruled {
    border-block-start: 1px solid var(--border);
  }

  /* A screen of sections (shadcn's settings example): the sections as ghost links down the
  /* left, in groups under small muted labels, the page beside them. */

  .section-layout {
    align-items: start;
    display: grid;
    gap: 2.5rem;
    grid-template-columns: 13rem minmax(0, 1fr);

    @media (width < 60rem) {
      gap: 1rem;
      grid-template-columns: minmax(0, 1fr);
    }
  }

  /* The page beside the nav sizes itself by its own width, not the window's. */
  .section-layout__page {
    container: section-page / inline-size;
    min-inline-size: 0;
  }

  .section-layout__page > .with-sidebar {
    @media (width >= 64rem) {
      align-items: stretch;
      flex-direction: column;

      > :last-child {
        inline-size: auto;
        position: static;
      }
    }

    @container section-page (width >= 54rem) {
      align-items: flex-start;
      flex-direction: row;

      > :last-child {
        flex-shrink: 0;
        inline-size: 18rem;
      }

      &.with-sidebar--sticky > :last-child {
        inset-block-start: calc(var(--app-header-height) + 1.5rem);
        position: sticky;
      }
    }
  }

  .section-nav {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    inset-block-start: calc(var(--app-header-height) + 1.5rem);
    max-block-size: calc(100dvh - var(--app-header-height) - 3rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    position: sticky;

    @media (width < 60rem) {
      border-block-end: 1px solid var(--border);
      flex-direction: row;
      gap: 0.25rem;
      max-block-size: none;
      overflow-x: auto;
      overflow-y: visible;
      padding-block-end: 0.5rem;
      position: static;
    }
  }

  .section-nav__group {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;

    @media (width < 60rem) {
      flex-direction: row;
    }
  }

  .section-nav__heading {
    color: var(--muted-foreground);
    font-size: var(--text-xs);
    font-weight: 500;
    margin: 0;
    padding: 0 0.75rem 0.25rem;

    @media (width < 60rem) {
      display: none;
    }
  }

  .section-nav__list {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    list-style: none;
    margin: 0;
    padding: 0;

    @media (width < 60rem) {
      flex-direction: row;

      li {
        display: contents;
      }
    }
  }

  .section-nav__link {
    --icon-size: 1rem;

    align-items: center;
    block-size: 2.25rem;
    border-radius: var(--radius-md);
    color: var(--foreground);
    display: flex;
    font-size: var(--text-sm);
    font-weight: 500;
    gap: 0.5rem;
    padding-inline: 0.75rem;
    text-decoration: none;
    white-space: nowrap;

    .icon {
      color: var(--muted-foreground);
    }

    &:hover {
      background-color: var(--accent);
      text-decoration: underline;
      text-underline-offset: 4px;
    }

    &[aria-current]:not([aria-current="false"]) {
      background-color: var(--muted);
      text-decoration: none;

      .icon {
        color: var(--foreground);
      }
    }
  }

  /* KPI row: the dashboard example's section cards (shared/_kpi_tile) — a ui-card each, the
  /* label its description, the figure its title, the trend an outline badge in its action slot,
  /* the note in its footer. Tinted from the primary at 5% down to the card, as that example
  /* does, so a row of them reads as one strip. */
  .kpi-row {
    display: grid;
    gap: 1rem;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  }

  .kpi-tile {
    background-image: linear-gradient(to top, color-mix(in oklch, var(--primary) 5%, var(--card)), var(--card));
    box-shadow: var(--shadow-xs);
    color: inherit;
    container: card / inline-size;
    font: inherit;
    text-align: start;
    text-decoration: none;
  }

  .kpi-tile--link {
    cursor: pointer;

    &:hover {
      border-color: var(--ring);
    }

    &:focus-visible {
      box-shadow: var(--ring-focus);
      outline: none;
    }
  }

  .ui-card__footer.kpi-tile__footer {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.375rem;

    .chart {
      inline-size: 100%;
    }
  }

  /* The footer's lead line when the figure is a warning or worse: medium weight, the icon in
  /* the tone. */
  .kpi-tile__alert {
    align-items: center;
    display: inline-flex;
    font-size: var(--text-sm);
    font-weight: 500;
    gap: 0.375rem;

    .icon {
      --icon-size: 1rem;
    }
  }

  .kpi-tile__alert--warning .icon { color: var(--warning); }
  .kpi-tile__alert--danger .icon { color: var(--destructive); }

  .kpi-tile__suffix {
    display: inline;
    font-variant-numeric: normal;
  }

  .kpi-tile__trend--down {
    rotate: 180deg;
  }

  /* The trend's arrow in the news's tone: spend up is bad news, conversions up good. */
  .kpi-tile__trend-badge[data-tone="success"] .kpi-tile__trend { color: var(--success); }
  .kpi-tile__trend-badge[data-tone="danger"] .kpi-tile__trend { color: var(--destructive); }

  /* A triage (shared/_attention, _attention_sheet, _attention_items): a Card (or Sheet) whose
  /* title carries the severity's icon in its tone, over a group of Items whose media is each
  /* item's severity icon in its tone. Hooks: .attention--<severity>, .attention__item--<severity>. */
  .attention__headline {
    align-items: center;
    display: flex;
    gap: 0.5rem;
  }

  .attention__icon {
    --icon-size: 1rem;
  }

  .attention--success .attention__icon { color: var(--success); }
  .attention--info .attention__icon { color: var(--muted-foreground); }
  .attention--warning .attention__icon { color: var(--warning); }
  .attention--danger .attention__icon { color: var(--destructive); }

  .attention__list {
    margin: 0;
  }

  .attention__item--info .attention__mark { color: var(--muted-foreground); }
  .attention__item--warning .attention__mark { color: var(--warning); }
  .attention__item--danger .attention__mark { color: var(--destructive); }

  .attention__message {
    font-weight: 400;
  }

  .attention-sheet .attention__list {
    overflow-y: auto;
  }

  /* A list's filters: search, then a select per field, wrapping. */

  .filter-bar {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;

    .ui-select {
      inline-size: auto;
      min-inline-size: 9rem;
    }
  }

  .filter-bar__search {
    inline-size: min(16rem, 100%);
  }

  /* A list's bulk actions (shared/_bulk_bar): All, then the verbs at the end, a muted strip
  /* over the rows. */
  .bulk-bar {
    align-items: center;
    background-color: var(--muted);
    border-block-end: 1px solid var(--border);
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
  }

  .status-links__link {
    white-space: nowrap;
  }

  .status-links__count {
    font-variant-numeric: tabular-nums;
  }

  /* An image field as a drop zone (shared/_image_dropzone): a dashed box the file input covers,
  /* so dropping on it and clicking it are the browser's own. It lights up while a file is dragged
  /* over it (--over) and shows the image it holds, its prompt shrinking under it (--filled). */
  .image-dropzone {
    align-items: center;
    border: 1px dashed var(--input);
    border-radius: var(--radius-lg);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    justify-content: center;
    min-block-size: 9rem;
    padding: 1rem;
    position: relative;
    text-align: center;
    transition: border-color 150ms, background-color 150ms;

    &:hover,
    &:focus-within,
    &.image-dropzone--over {
      background-color: var(--muted);
      border-color: var(--ring);
    }
  }

  .image-dropzone__preview {
    display: contents;
  }

  .image-dropzone__preview img {
    max-block-size: 6rem;
    max-inline-size: 100%;
    object-fit: contain;
  }

  .image-dropzone__prompt {
    align-items: center;
    color: var(--muted-foreground);
    display: inline-flex;
    font-size: var(--text-sm);
    gap: 0.375rem;

    .icon {
      --icon-size: 1rem;
    }

    .image-dropzone--filled & {
      font-size: var(--text-xs);
    }
  }

  .image-dropzone__file {
    cursor: pointer;
    inset: 0;
    opacity: 0;
    position: absolute;
  }

  .status-links {
    inline-size: fit-content;
    max-inline-size: 100%;
    overflow-x: auto;
  }

  /* A column header that sorts the list (TablesHelper#sortable_header). */
  .sortable-header {
    align-items: center;
    color: inherit;
    display: inline-flex;
    gap: 0.25rem;
    text-decoration: none;

    &:hover {
      color: var(--foreground);
    }
  }

  .sortable-header--active {
    color: var(--foreground);
  }

  .sortable-header__desc {
    rotate: 180deg;
  }

  .ui-table__empty {
    color: var(--muted-foreground);
    padding-block: 2rem;
    text-align: center;
  }

  /* A table inside a card, edge to edge: the card's hairline is the table's frame. */
  .ui-card--flush > .ui-table-container,
  .ui-card--flush > .ui-table {
    border: 0;
    border-radius: 0;
  }

  /* Dialog and sheet extras: a form that is the dialog's body, a wider sheet. */
  .ui-dialog__form {
    display: grid;
    gap: 1rem;
  }

  .ui-sheet--wide {
    inline-size: min(48rem, 100vw);
    max-inline-size: 100vw;
  }

  /* The command menu (layouts/shared/_global_search, shadcn's Command in a Dialog). */
  .global-search {
    gap: 0;
    inline-size: min(36rem, calc(100vw - 2rem));
    inset-block-start: 15dvh;
    margin-block-start: 0;
    overflow: hidden;
    padding: 0;
  }

  .global-search__field {
    align-items: center;
    border-block-end: 1px solid var(--border);
    display: flex;
    gap: 0.5rem;
    padding-inline: 0.75rem;

    > .icon {
      --icon-size: 1rem;

      color: var(--muted-foreground);
    }
  }

  .global-search__input {
    background: none;
    block-size: 3rem;
    border: 0;
    color: var(--foreground);
    flex: 1;
    font: inherit;
    font-size: var(--text-sm);
    outline: none;
  }

  .global-search__results {
    max-block-size: min(24rem, 60dvh);
    overflow-y: auto;
  }

  .global-search__empty {
    color: var(--muted-foreground);
    font-size: var(--text-sm);
    padding: 1.5rem;
    text-align: center;
  }

  /* A sortable row's grip and its move and remove buttons. */
  .sortable-row--dragging {
    opacity: 0.5;
  }

  .drag-handle {
    color: var(--muted-foreground);
    cursor: grab;
    padding-inline: 0.25rem;
    user-select: none;
  }

  .row-moves {
    align-items: center;
    display: flex;
    flex-shrink: 0;
  }

  .row-moves__down {
    rotate: 180deg;
  }

  .ui-button.row-moves__remove:hover {
    color: var(--destructive);
  }

  /* A secret's field: the eye inside the input group flips which icon shows. */
  .secret-field .secret-field__hide,
  .secret-field--shown .secret-field__show {
    display: none;
  }

  .secret-field--shown .secret-field__hide {
    display: inline-block;
  }

  /* A copy button that just copied. */
  .ui-button.is-copied {
    border-color: var(--success);
    color: var(--success);
  }

  /* A confirm dialog's trigger for a destructive act (layouts/shared/_confirm_dialog,
  /* negative:): an outline button in red words; the dialog's own button is the solid one. */
  .ui-button.confirm-trigger--negative {
    color: var(--destructive);
  }

  /* A delete that reads as a red link (layouts/shared/_delete_dialog's trigger_text). */
  .delete-link {
    background: none;
    border: 0;
    color: var(--destructive);
    cursor: pointer;
    font: inherit;
    padding: 0;

    &:hover {
      text-decoration: underline;
      text-underline-offset: 4px;
    }
  }

  /* A list with bullets (an alert's errors). */
  .bullet-list {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    list-style: disc;
    margin: 0;
    padding-inline-start: 1.25rem;
  }
}

/* A record's facts as a description list (shadcn's: muted labels in a fixed column, values
/* beside them); --wide for longer labels. */
@layer ui {
  .description-list {
    display: grid;
    font-size: var(--text-sm);
    gap: 0.5rem 1rem;
    grid-template-columns: 7rem minmax(0, 1fr);
    margin: 0;

    > dt {
      color: var(--muted-foreground);
    }

    > dd {
      margin: 0;
      min-inline-size: 0;
      overflow-wrap: anywhere;
    }
  }

  .description-list--wide {
    grid-template-columns: 10rem minmax(0, 1fr);
  }
}

/* A drop target while something is dragged over it (drag_and_drop_controller's hover class on
/* a board lane): the ring a focused control has, so where it will land is plain. */
@layer ui {
  .drag-and-drop__hover-container {
    box-shadow: 0 0 0 2px var(--ring);
  }
}
