/*
 * Project styles for CER.
 * Loaded after Bootstrap in components/layout.blade.php, so rules here win.
 * Served directly from public/ -- there is no build step.
 */

/* ---------- Tokens ---------- */

:root {
  --bs-primary: #0B3B5C;
  --bs-primary-rgb: 11, 59, 92;
  --bs-link-color: #0B3B5C;
  --bs-link-hover-color: #08304B;
  --bs-border-radius: .5rem;          /* cards */
  --bs-border-radius-sm: .375rem;     /* controls */
  --bs-body-font-size: .9375rem;
  --bs-body-bg: #DCE3E7;

  /* Register state colours. Urgency only -- never categories. */
  --cer-muted:   #5D6E76;
  --cer-line:    #C9D4DA;
  --cer-hover:   #E4EAEE;
  --cer-warn-fg: #9A3412; --cer-warn-bg: #FBE9DA; --cer-warn-bd: #F0C9A6;
  --cer-crit-fg: #A31621; --cer-crit-bg: #FBE4E5; --cer-crit-bd: #F0BFC2;
  --cer-ok-fg:   #14653B; --cer-ok-bg:   #DFF1E6; --cer-ok-bd:   #B4DCC3;
  --cer-work:    #6D3FC8;
}

/*
 * .card defaults --bs-card-bg to var(--bs-body-bg), so cards would be the
 * same colour as the page. Give them their own slightly-off-white surface.
 */
.card {
  --bs-card-bg: #EFF3F5;
  --bs-card-border-color: #C9D4DA;
}

/*
 * Anything set in :root above must be restated here. Both selectors have the
 * same specificity, and app.css loads after Bootstrap, so the :root values
 * would otherwise win in dark mode too and the backgrounds would never change.
 */
[data-bs-theme="dark"] {
  --bs-primary: #4F9FD4;              /* #0B3B5C fails contrast on dark */
  --bs-primary-rgb: 79, 159, 212;
  --bs-link-color: #4F9FD4;
  --bs-link-hover-color: #7ABBE4;
  --bs-body-bg: #0C1417;

  --cer-muted:   #90A3AB;
  --cer-line:    #24343B;
  --cer-hover:   #18272D;
  --cer-warn-fg: #FBBF24; --cer-warn-bg: #33240F; --cer-warn-bd: #59401A;
  --cer-crit-fg: #FB7185; --cer-crit-bg: #38161C; --cer-crit-bd: #5C2831;
  --cer-ok-fg:   #4ADE80; --cer-ok-bg:   #102A1B; --cer-ok-bd:   #1F4B32;
  --cer-work:    #A98BF5;
}

[data-bs-theme="dark"] .card {
  --bs-card-bg: #131E23;
  --bs-card-border-color: #24343B;
}

/* ---------- Components ---------- */

/*
 * Button variants carry their own compiled --bs-btn-* set and never read
 * --bs-primary, so the brand colour has to be restated here.
 */
.btn-primary {
  --bs-btn-bg: #0B3B5C;        --bs-btn-border-color: #0B3B5C;
  --bs-btn-hover-bg: #0B3B5C;  --bs-btn-hover-border-color: #0B3B5C;
  --bs-btn-active-bg: #0B3B5C; --bs-btn-focus-shadow-rgb: 11, 59, 92;
}

/*
 * Hover lifts the same colour rather than swapping to a darker one, so the
 * button never reads as a different shade of blue mid-interaction.
 */
.btn-primary:hover { filter: brightness(1.18); }
.btn-primary:active { filter: brightness(.92); }

.form-check-input { margin-top: .30em; }

/*
 * The navbar carries data-bs-theme="dark" so its links render light. That
 * also swaps --bs-primary to the dark-theme value inside it, so bg-primary
 * would paint the navbar in the lighter blue. Pin the background instead.
 */
.navbar.bg-primary {
  background-color: #0B3B5C !important;
}

/* ---------- Register table ---------- */

/*
 * Sticky headers only stick inside a scroll container that has a height.
 * .table-responsive alone won't do it: overflow-x: auto computes overflow-y
 * to auto as well, which cuts the table off from page scrolling. So the
 * wrapper gets an explicit max-height and does the scrolling itself.
 */
.reg-scroll {
  max-height: 70vh;
  overflow: auto;

  /* Standard properties -- Firefox, and Chrome 121+ */
  scrollbar-width: thin;
  scrollbar-color: var(--cer-line) transparent;
}

/*
 * WebKit's older prefixed API, still what Safari and older Chrome use. It has
 * to be written separately -- the two syntaxes don't alias each other.
 */
.reg-scroll::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
.reg-scroll::-webkit-scrollbar-track {
  background: transparent;
}
.reg-scroll::-webkit-scrollbar-thumb {
  background: var(--cer-line);
  border-radius: 999px;
  /* Transparent border + background-clip insets the thumb without changing the
     track's hit area, so it reads as a slim pill in a wider gutter. */
  border: 3px solid transparent;
  background-clip: content-box;
}
.reg-scroll::-webkit-scrollbar-thumb:hover {
  background: var(--cer-muted);
  background-clip: content-box;
}
.reg-scroll::-webkit-scrollbar-corner {
  background: transparent;
}

/*
 * Bootstrap 5.3 paints table cells with an inset box-shadow rather than a
 * background, so a plain `background` on the row loses to it. Set its own
 * variables instead of fighting them.
 */
.reg {
  --bs-table-bg: transparent;
  --bs-table-hover-bg: var(--cer-hover);
  --bs-table-hover-color: var(--bs-body-color);
  --bs-table-border-color: var(--cer-line);
}

.reg thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bs-card-bg);
  border-bottom: 1px solid var(--cer-line);
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--cer-muted);
  white-space: nowrap;
}

/* Bootstrap's paginator view ships its own utility classes; these just tone
   the summary text down to match the rest of the page. */
.reg-pagination .pagination { --bs-pagination-font-size: .84rem; margin-bottom: 0; }
.reg-pagination p { font-size: .82rem; color: var(--cer-muted); margin-bottom: 0; }

/* ---- Sortable headings ---- */

.sort-th { padding: 0 !important; }

.sort-link {
  display: flex;
  align-items: center;
  gap: .35rem;
  padding: 10px 14px;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}
.sort-link:hover { color: var(--bs-primary); }

/* Dimmed until hovered or active, so seven arrows don't shout at once. */
.sort-arrow { opacity: .35; font-size: .9em; }
.sort-th:hover .sort-arrow,
.sort-th-active .sort-arrow { opacity: 1; }
.sort-th-active .sort-link { color: var(--bs-primary); }

.reg tbody td {
  height: 52px;                       /* fixed row height aids scanning */
  vertical-align: middle;
  font-size: .84rem;
}

/* Description on top, manufacturer + model beneath. Halves the column count. */
.reg-sub {
  display: block;
  margin-top: 1px;
  font-size: .76rem;
  font-weight: 400;
  color: var(--cer-muted);
}

/* tabular-nums is what makes a wrong serial visible at a glance */
.reg-ref {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-variant-numeric: tabular-nums;
  font-size: .78rem;
  color: var(--cer-muted);
  white-space: nowrap;
}
.reg-ref b { color: var(--bs-body-color); font-weight: 600; }

.reg a.reg-link {
  color: var(--bs-body-color);
  text-decoration: none;
  font-weight: 600;
}
.reg tbody tr:hover a.reg-link { color: var(--bs-primary); }

/* ---------- Status + chips ---------- */

.status {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  white-space: nowrap;
  font-size: .8rem;
}
.status::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--cer-muted);
  flex: none;
}
.status-work::before  { background: var(--cer-work); }
.status-await::before { background: var(--cer-warn-fg); }
.status-done::before  { background: var(--cer-ok-fg); }
.status-lost::before  { background: var(--cer-crit-fg); }

/*
 * Outline by default. Only hazard, overdue and damaged get a filled variant,
 * so at most one chip per row should be shouting.
 */
.chip {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  padding: .12rem .45rem;
  border: 1px solid var(--cer-line);
  border-radius: var(--bs-border-radius-sm);
  background: transparent;
  color: var(--cer-muted);
  font-size: .7rem;
  font-weight: 600;
  white-space: nowrap;
}
.chip-warn { color: var(--cer-warn-fg); background: var(--cer-warn-bg); border-color: var(--cer-warn-bd); }
.chip-crit { color: var(--cer-crit-fg); background: var(--cer-crit-bg); border-color: var(--cer-crit-bd); }
.chip-ok   { color: var(--cer-ok-fg);   background: var(--cer-ok-bg);   border-color: var(--cer-ok-bd); }

/* ---------- Row actions ---------- */

/* Shrink-to-fit column pinned to the right edge of the table. */
.reg-actions {
  width: 1%;
  white-space: nowrap;
  text-align: right;
}
.reg-actions .btn,
.reg-card-meta .btn {
  --bs-btn-padding-y: .15rem;
  --bs-btn-padding-x: .5rem;
  --bs-btn-font-size: .9rem;
  line-height: 1;
}

/* ---------- Mobile cards ---------- */

/*
 * A flex child will not shrink below its own content unless told to, so a long
 * description pushes the tags and the kebab off the right edge. min-width: 0
 * lets the title give way instead; the tags and kebab keep their size.
 */
.reg-card-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: .5rem;
}
.reg-card-top .reg-link {
  min-width: 0;
  overflow-wrap: anywhere;
}
.reg-card-meta {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex: 0 0 auto;
}

/* Tags get the card's full width so every one of them shows and they wrap,
   rather than competing with the title for the top row. */
.reg-cards .chips {
  display: flex;
  margin-top: .35rem;
}

/*
 * The kebab is the only tap target in the row, so on touch it has to meet the
 * 44px minimum -- gloved hands at the goods-in bench. On desktop it stays
 * compact so it doesn't compete with the status and tag columns.
 */
@media (hover: none) {
  .reg-actions .btn {
    --bs-btn-padding-y: .6rem;
    --bs-btn-padding-x: .9rem;
  }
}

/* ---------- Forms ---------- */

/* Section heading inside a form card. Matches the table header treatment. */
.form-section {
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--cer-muted);
  margin: 0 0 1rem;
}

.cer-form .form-label {
  font-size: .82rem;
  font-weight: 600;
  margin-bottom: .3rem;
}

.cer-form .form-text {
  font-size: .76rem;
  color: var(--cer-muted);
}

/*
 * -lg controls are here for the touch target, not the type size. Bootstrap ties
 * the two together at 1.25rem, which reads a third larger than the page. Keep
 * the generous padding, drop the font back to body size.
 */
.cer-form .form-control-lg,
.cer-form .form-select-lg,
.cer-form .input-group-lg > .form-control,
.cer-form .input-group-lg > .form-select {
  font-size: 1rem;
}

.req {
  color: var(--cer-crit-fg);
  font-weight: 600;
}

/* Item cards sit inside the receipt form, so they read as nested, not peers. */
.item-card {
  border-left: 3px solid var(--bs-primary);
}

/* The two RMA buttons sit beside the select, so they want to read as controls
   attached to it rather than as actions of their own. */
.input-group .repeat-rma,
.input-group [data-new-rma] {
  --bs-btn-font-size: .8rem;
  --bs-btn-padding-x: .7rem;
  white-space: nowrap;
  color: var(--cer-muted);
}
.input-group .repeat-rma:hover,
.input-group [data-new-rma]:hover {
  color: var(--bs-body-color);
}

.item-flags {
  border-top: 1px solid var(--cer-line);
  padding-top: .75rem;
}
.item-flags .form-check-label { font-size: .88rem; }

/*
 * Briefly marks the card a deep link pointed at. The transition lives on the
 * card itself, not the modifier, so removing the class fades out rather than
 * snapping off.
 */
.item-card {
  transition: box-shadow .4s ease-out, border-left-color .4s ease-out;
}
.item-card-targeted {
  border-left-color: var(--cer-warn-fg);
  box-shadow: 0 0 0 .2rem rgba(var(--bs-primary-rgb), .15);
}

/* The collapsed card header doubles as the expand control. */
.item-toggle {
  color: inherit;
  display: flex;
  align-items: baseline;
  gap: .6rem;
}
.item-toggle .item-summary {
  font-size: .86rem;
  font-weight: 600;
  color: var(--bs-body-color);
}
.item-toggle::after {
  content: "▾";
  margin-left: auto;
  color: var(--cer-muted);
  transition: transform .15s ease-out;
}
.item-toggle[aria-expanded="false"]::after { transform: rotate(-90deg); }

/*
 * On a phone the submit would sit below two cards of inputs. Pin it to the
 * bottom of the viewport so it is always reachable at the bench; on desktop it
 * stays in the flow.
 */
@media (max-width: 767.98px) {
  .cer-form-actions {
    position: sticky;
    bottom: 0;
    padding: .75rem 0;
    background: var(--bs-body-bg);
    border-top: 1px solid var(--cer-line);
  }
  .cer-form-actions .btn { flex: 1 1 0; }
}

/* ---------- Finish ---------- */

/*
 * Only background-color, opacity and transform are transitioned. Anything
 * that animates layout (height, width, margin) recalculates every frame
 * and judders.
 */
.btn,
.nav-link,
.form-control,
.table tbody tr {
  transition: background-color .15s ease-out,
              opacity .15s ease-out,
              transform .12s ease-out,
              border-color .15s ease-out;
}

.btn:active { transform: translateY(1px); }

:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--bs-primary);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
  }
  .btn:active { transform: none; }
}
