/* Palo603 site style. One file for every page.
   Read top to bottom: settings → header → sidebar → tabs → content → phone changes. */

/* ---- Settings: change a color here and it changes everywhere ---- */
:root {
  --blue: #2774AE;            /* UCLA Blue */
  --black: #000000;
  --white: #ffffff;
  --line: rgba(255, 255, 255, 0.8);       /* main frame lines */
  --line-soft: rgba(255, 255, 255, 0.2);  /* quiet separators */
  --text-soft: rgba(255, 255, 255, 0.7);
  --fill: rgba(255, 255, 255, 0.1);       /* card image background */
  --search-bg: #374151;

  --header-h: 80px;
  --tabs-h: 60px;
  --side-w: 210px;
  --card: 8rem;               /* card image: 128 px */
  --gap: 1.25rem;             /* 20 px between cards */

  color-scheme: dark;         /* dark scrollbars and form controls */
}

/* Pacifico: our own copy (static/fonts/, SIL Open Font License), Latin letters only. */
@font-face {
  font-family: "Pacifico";
  src: url("/static/fonts/pacifico-latin.woff2") format("woff2");
  font-display: swap;         /* show text in a fallback font until the file has arrived */
}

/* ---- Base ---- */
*, *::before, *::after { box-sizing: border-box; } /* width includes padding + border */

html {
  /* Jumping to /#fasteners must not hide the heading under the sticky header + tabs. */
  scroll-padding-top: calc(var(--header-h) + var(--tabs-h) + 1rem);
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; } /* respect "reduce motion" in the device settings */
}

body {
  margin: 0;
  min-width: 320px;
  background: var(--black);
  color: var(--white);
  /* Fonts every device already has: Georgia (Windows, Mac, iPhone), Noto Serif (Android).
     They have no Korean letters, so for those the browser moves down the list to a Korean font
     (sans-serif: Korean serif system fonts look dated on screen). */
  font-family: Georgia, "Noto Serif", "DejaVu Serif", "Apple SD Gothic Neo", "Malgun Gothic",
    "Noto Sans KR", "Noto Sans CJK KR", serif;
  line-height: 1.5;
}

/* Korean: break lines only between words (at spaces), never inside a word like 프로파|일. */
html[lang="ko"] body { word-break: keep-all; overflow-wrap: anywhere; }

a { color: inherit; }
.script { font-family: "Pacifico", cursive; font-weight: normal; }

/* ---- Header ---- */
.site-header {
  position: sticky;           /* stays at the top while the page scrolls */
  top: 0;
  z-index: 50;
  height: var(--header-h);
  display: flex;
  align-items: center;
  background: var(--black);
}

.logo {
  flex: 0 0 var(--side-w);    /* same width as the sidebar below it */
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--blue);
  font-family: "Pacifico", cursive;
  font-size: 2.25rem;
  color: var(--white);
  text-decoration: none;
}

.search {
  flex: 1;
  display: flex;
  justify-content: center;
  padding: 0 1.5rem;
}
.search input {
  width: 100%;
  max-width: 600px;
  padding: 0.75rem 1.25rem;
  border: 0;
  border-radius: 4px;
  background: var(--search-bg);
  color: var(--white);
  font: inherit;
  font-size: 1.125rem;
  transition: max-width 0.3s;
}
.search input:focus {
  max-width: 900px;           /* grows while typing, like the prototype */
  outline: 2px solid var(--blue);
}

/* Header buttons + their panels.
   The panel hangs under the whole button row, a small gap below it. While a panel is open,
   site.js draws ONE white outline around "button + panel" (an SVG, like the card hover boxes),
   and the button's and panel's own borders turn invisible: no double lines, rounded joins.
   The gap keeps the panel's top line away from the other buttons' bottom lines.
   Hovering from the button into the panel keeps it open, because the panel is inside .action. */
.actions {
  position: relative;         /* panels and the outline are placed relative to this row */
  display: flex;
  gap: 1rem;
  margin-right: 1rem;
  --panel-gap: 8px;
}
.action > button {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1.25rem;
  border: 2px solid var(--white);
  border-radius: 4px;
  background: var(--black);
  color: var(--white);
  font: inherit;
  font-size: 1.125rem;
  cursor: pointer;
}
.action svg {
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.panel {
  display: none;
  position: absolute;
  top: calc(100% + var(--panel-gap));
  left: 0;
  right: 0;
  z-index: 2;
  padding: 1.25rem;
  border: 2px solid var(--white);
  border-radius: 4px;
  background: var(--black);
}
/* Open = .open (set by site.js). Without JavaScript: hover or keyboard focus instead. */
.action.open .panel,
html:not(.js) .action:hover .panel,
html:not(.js) .action:focus-within .panel { display: block; }
.action.open > button,
.action.open .panel {
  z-index: 2;                 /* above the outline's black fill */
  border-color: transparent;  /* the outline replaces them */
  background: transparent;
}
/* An invisible bridge over the gap: the mouse can travel from button to panel without
   "leaving" the button, so the hover preview stays open. */
.action.open > button::after,
html:not(.js) .action:hover > button::after {
  content: "";
  position: absolute;
  top: 100%;
  left: -2px;
  right: -2px;
  height: calc(var(--panel-gap) + 4px);
}
.panel-frame {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  overflow: visible;
  pointer-events: none;       /* clicks go through to what is underneath */
}
.panel-frame path { fill: var(--black); stroke: var(--white); stroke-width: 2; }
.panel p { margin: 0 0 0.75rem; }
.panel-link {
  display: block;
  margin-bottom: 0.75rem;
  padding: 0.6rem 0.9rem;
  border: 1px solid var(--line-soft);
  border-radius: 4px;
  text-decoration: none;
}
.panel-link:hover { border-color: var(--white); }
.panel-note { color: var(--text-soft); font-size: 0.875rem; }

/* ---- Sidebar + main area ---- */
.shell {
  display: grid;
  grid-template-columns: var(--side-w) 1fr;
}

/* The phone toggle checkbox is invisible; its label is the visible control. */
.nav-toggle {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.sidebar {
  position: sticky;           /* the sidebar stays put while the cards scroll */
  top: var(--header-h);
  height: calc(100vh - var(--header-h));
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;                  /* a slim, dark scrollbar when the list is long */
  scrollbar-color: #444 var(--black);
  border-right: 1px solid var(--line);
}
.sidebar-head {
  display: flex;
  align-items: center;
  height: var(--tabs-h);
  margin: 0 10px;
  padding-left: 0.25rem;
  border-bottom: 1px solid var(--line);
  font-size: 1.25rem;
}
.nav-label { flex: 1; display: flex; align-items: center; justify-content: space-between; }
.sidebar-head .caret { display: none; } /* only used on phones */
.groups {
  margin: 0;
  padding: 1rem;
  list-style: none;
  font-size: 0.875rem;
}
.groups li + li { margin-top: 0.5rem; }
html:not(.js) .groups + .groups { margin-top: 1rem; } /* without JavaScript all lists are shown */
.groups-title { font-weight: 600; }
/* With JavaScript: only the active sheet's list, and no list titles. */
html.js .groups:not(.active),
html.js .groups-title { display: none; }
/* A group: its button + the ▲ toggle, and the folded list of its sub-categories under them. */
.group-row { display: flex; gap: 0.5rem; }
.group-link {
  flex: 1;
  display: block;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--line-soft);
  border-radius: 4px;
  background: #1a1a1a;
  text-decoration: none;
}
.group-link:hover { border-color: rgba(255, 255, 255, 0.6); background: #222; }
.group-link.selected { border-color: var(--blue); background: var(--blue); }

/* ▲ = folded, ▼ = unfolded (as in the prototype). The arrow is drawn by CSS from aria-expanded,
   the attribute that also tells screen readers whether the list is open. */
.toggle {
  flex: 0 0 2.25rem;
  height: 2.25rem;
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 4px;
  background: var(--black);
  color: var(--white);
  cursor: pointer;
}
.toggle::before { content: "▲"; font-size: 0.75rem; }
.toggle[aria-expanded="true"]::before { content: "▼"; }
.toggle:hover { background: var(--white); color: var(--black); }
.expand-all { margin-left: 0.5rem; }

.sub {
  margin: 0.5rem 0 0;
  padding-left: 0.75rem;
  border-left: 1px solid var(--line-soft);
  list-style: none;
}
.group-item:not(.expanded) .sub { display: none; }
.sub-link {
  display: block;
  padding: 0.4rem 0.75rem;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 4px;
  background: #0a0a0a;
  text-decoration: none;
}
.sub-link:hover { border-color: rgba(255, 255, 255, 0.6); background: #1a1a1a; }
.sub-link.current { border-color: var(--blue); }

.main { min-width: 0; }        /* lets the tabs/table scroll inside instead of widening the page */

/* ---- Sheet tabs ---- */
.tabs {
  position: sticky;
  top: var(--header-h);
  z-index: 10;
  display: flex;
  height: var(--tabs-h);
  border-bottom: 1px solid var(--white);
  background: var(--black);
}
.tabs a {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-right: 1px solid var(--line);
  font-size: 0.875rem;
  text-decoration: none;
  white-space: nowrap;
}
.tabs a:last-child { border-right: 0; }
.tabs a:hover { background: var(--fill); }
.tabs a[aria-current="page"] {
  /* the active tab opens into the page below it: no bottom line */
  border-top: 2px solid var(--white);
  border-bottom: 2px solid var(--black);
  margin-bottom: -1px;
}

/* ---- Content ---- */
.content { padding: 1.5rem; }

/* Sheets: with JavaScript only the active one is shown (the tab says which);
   without, all are stacked under their titles. */
.sheet + .sheet { margin-top: 3rem; }
.sheet-title { margin: 0 0 1.5rem; font-size: 1.5rem; }
html.js .sheet:not(.active),
html.js .sheet-title { display: none; }

.group + .group { margin-top: 2rem; }
.group h2 {
  margin: 0 0 1rem;
  font-size: 1.125rem;
  font-weight: 600;
}
/* The marked group (clicked in the sidebar; site.js). Without JavaScript: the one in the address. */
.group.selected h2,
html:not(.js) .group:target h2 { color: var(--blue); }

.cards {
  position: relative;         /* the hover frame (site.js) is drawn relative to this */
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
  max-width: calc(7 * var(--card) + 6 * var(--gap)); /* at most 7 cards per row */
}
.card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  width: var(--card);
  text-decoration: none;
}
.card-img {
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1;            /* square */
  overflow: hidden;
  border-radius: 4px;
  background: var(--fill);
  font-size: 3rem;
}
.card-img img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;          /* fill the square, cropping if needed */
}
.card:hover .card-img { background: var(--line-soft); }
.card:hover .card-img img { opacity: 0.85; }
.card-name {
  font-size: 0.875rem;
  text-align: center;
  color: var(--text-soft);
}

.empty { margin: 0; color: var(--text-soft); font-size: 0.875rem; }

/* Hover previews (desktop; site.js). The box is put right after the last card of the hovered
   card's row; flex-basis 100% makes it take a whole row of its own. Its outline is not a CSS
   border: the frame (one SVG line with rounded corners) goes around card and box together. */
.preview {
  flex-basis: 100%;
  padding: calc(1.5rem + 2px);
}
.preview .cards { max-width: none; }
.frame {
  position: absolute;
  top: 0;
  left: 0;
  overflow: visible;
  pointer-events: none;       /* the mouse goes "through" it to the cards */
}
.frame path { fill: none; stroke: var(--white); stroke-width: 2; }
@media (hover: hover) {
  /* A card without sub-categories (it opens a page) gets a white outline instead. */
  .card:not([data-kids]):hover { outline: 2px solid var(--white); outline-offset: 4px; border-radius: 4px; }
}

/* Category page: where we are, then the title. */
.breadcrumb { margin-bottom: 0.5rem; font-size: 0.875rem; color: var(--text-soft); }
.breadcrumb a { text-decoration: none; }
.breadcrumb a:hover { text-decoration: underline; color: var(--white); }
.breadcrumb .sep { margin: 0 0.5rem; opacity: 0.5; }
.page-title { margin: 0 0 1.25rem; font-size: 1.25rem; }

/* ---- Family page ---- */
.clear { margin-left: auto; font-size: 0.75rem; color: var(--text-soft); }
.clear:hover { color: var(--white); }

.filters { padding: 0.5rem 1rem 1rem; font-size: 0.875rem; }
.filter {
  margin: 0;
  padding: 0.75rem 0;
  border: 0;
  border-top: 1px solid var(--line-soft);
  min-width: 0;
}
.filter legend { float: left; width: 100%; padding: 0; margin-bottom: 0.5rem; font-weight: 600; }
.check { clear: both; display: flex; gap: 0.5rem; align-items: baseline; padding: 0.15rem 0; cursor: pointer; }
.filters > .check { padding: 0.5rem 0 0.75rem; }
.filter details { clear: both; }
.filter summary { padding: 0.2rem 0; cursor: pointer; }
.filter details .check { padding-left: 1rem; }

/* Value and picture buttons: a real checkbox (invisible, still reachable with Tab and Space)
   inside a label; the span after it is what you see, white when the box is ticked. */
.opts { clear: both; display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.375rem; }
.filter-pictures .opts { grid-template-columns: repeat(2, 1fr); }
.opt { position: relative; }
.opt input { position: absolute; opacity: 0; pointer-events: none; }
.opt span {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  height: 100%;
  padding: 0.375rem 0.25rem;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 4px;
  font-size: 0.75rem;
  text-align: center;
  cursor: pointer;
}
.opt:hover span { border-color: rgba(255, 255, 255, 0.6); }
.opt input:checked + span { border-color: var(--white); background: var(--white); color: var(--black); }
.opt input:focus-visible + span { outline: 2px solid var(--blue); }
.icon { width: 2rem; height: 2rem; }
.flag { width: 1.5rem; height: 1rem; border-radius: 2px; outline: 1px solid rgba(255, 255, 255, 0.3); }
.action svg.flag { stroke: none; } /* flags keep their own colors, unlike the outlined icons */
.lang-link { display: flex; align-items: center; gap: 0.6rem; }
.lang-link.current { border-color: var(--blue); }
/* An option that would give no rows with the other choices (site.js). Still clickable. */
.unavailable { opacity: 0.35; }
.apply {
  width: 100%;
  margin-top: 1rem;
  padding: 0.6rem;
  border: 0;
  border-radius: 4px;
  background: var(--blue);
  color: var(--white);
  font: inherit;
  cursor: pointer;
}

.family-head { display: flex; gap: 1rem; align-items: center; margin-bottom: 1rem; }
.family-head img { flex: 0 0 auto; border-radius: 4px; }
.family-head .page-title { margin: 0; }
.code { margin-right: 0.25rem; font-weight: normal; color: var(--text-soft); }
.note { max-width: 60rem; margin: 0.25rem 0 0; font-size: 0.875rem; color: var(--text-soft); }
.count { margin: 0 0 0.5rem; font-size: 0.75rem; color: var(--text-soft); }

/* The table scrolls inside its box, both ways; the header row and the SKU column stay in view. */
.table-wrap {
  max-height: 75vh;
  overflow: auto;
  border: 1px solid var(--line-soft);
  scrollbar-color: #444 var(--black);
}
.variants { border-collapse: collapse; font-size: 0.875rem; white-space: nowrap; }
.variants th,
.variants td { padding: 0.5rem 1rem; border-bottom: 1px solid rgba(255, 255, 255, 0.1); text-align: left; }
.variants td { color: rgba(255, 255, 255, 0.85); }
.variants th { position: sticky; top: 0; z-index: 2; background: #0d0d0d; }
.variants th:first-child,
.variants td:first-child { position: sticky; left: 0; z-index: 1; background: var(--black); }
.variants th:first-child { z-index: 3; background: #0d0d0d; }
.variants tbody tr:hover td { background: #141414; }
.add {
  padding: 0.25rem 0.75rem;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 4px;
  background: none;
  color: rgba(255, 255, 255, 0.5);
  font: inherit;
  font-size: 0.75rem;
}
.none { margin: 0; padding: 1.5rem; text-align: center; color: var(--text-soft); }

.message { padding: 2rem 0; }
.message h1 { margin: 0 0 1rem; font-size: 2rem; }

/* ---- Phones and small tablets (narrower than 1024 px) ---- */
@media (max-width: 1023px) {
  :root { --header-h: 0px; } /* the header scrolls away on phones: screen space is precious */
  html { scroll-padding-top: calc(var(--tabs-h) + 1rem); }

  .site-header {
    position: relative;       /* not sticky, but still the top layer: panels must cover the tabs */
    height: auto;
    flex-wrap: wrap;
  }
  .logo {
    flex: 0 0 auto;
    padding: 0.5rem 1rem;
    font-size: 1.75rem;
  }
  .actions { margin-left: auto; gap: 0.5rem; }
  .action > button { padding: 0.5rem 0.75rem; }
  .action .label { display: none; } /* icons only; aria-label keeps the name for screen readers */
  .panel { left: auto; width: min(20rem, calc(100vw - 2rem)); } /* wider than the 3 icons, right-aligned */
  .search {
    order: 3;                 /* own row under logo + buttons */
    flex-basis: 100%;
    padding: 0.5rem 1rem;
  }
  .search input { font-size: 1rem; }

  .shell { display: block; }
  .sidebar {
    position: static;
    height: auto;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
  .sidebar-head {
    height: 48px;
    border-bottom: 0;
  }
  .nav-label { cursor: pointer; }
  .expand-all { display: none; }
  .sidebar-head .caret { display: inline; font-size: 0.875rem; }
  .groups, .filters { display: none; padding-top: 0; }
  .nav-toggle:checked ~ .sidebar .groups.active,             /* only the active sheet's list */
  html:not(.js) .nav-toggle:checked ~ .sidebar .groups,        /* without JavaScript: all lists */
  .nav-toggle:checked ~ .sidebar .filters { display: block; }   /* opened by tapping the label */
  .clear { margin-left: 1rem; }
  .family-head img { width: 64px; height: 64px; }
  .nav-toggle:checked ~ .sidebar .caret { transform: rotate(180deg); }
  .nav-toggle:focus-visible ~ .sidebar .sidebar-head { outline: 2px solid var(--blue); }

  .tabs {
    top: 0;
    overflow-x: auto;         /* tabs scroll sideways if they don't fit */
    scrollbar-width: none;    /* ...by swiping; no scrollbar strip under them */
  }
  .tabs a { flex: 0 0 auto; padding: 0 1.25rem; }

  .content { padding: 1rem; }
  .cards {
    display: grid;
    /* As many columns as fit with at least 6.5rem (104 px) each:
       small phone 2, phone 3, tablet 6. The columns share what is left over. */
    grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
    gap: 1rem;
  }
  .card { width: auto; }
  .variants th, .variants td { padding: 0.5rem 0.625rem; } /* more columns fit on the screen */
}

/* ---- Very small phones (narrower than 360 px): logo + 4 buttons must still fit on one row ---- */
@media (max-width: 359px) {
  .logo { padding: 0.5rem 0.75rem; font-size: 1.5rem; }
  .actions { gap: 0.25rem; margin-right: 0.5rem; }
  .action > button { padding: 0.5rem 0.375rem; }
}
