/* Shared by both libraries. Google-flavoured and deliberately plain: familiar
   beats distinctive for an internal tool the team opens a dozen times a day. */

:root {
  --bg: #ffffff;
  --fg: #202124;            /* Google grey 900 — body text */
  --muted: #5f6368;         /* Google grey 700 — secondary text */
  --line: #dadce0;          /* Google grey 300 — borders */
  --fill: #f1f3f4;          /* Google grey 100 — field + hover fill */
  --accent: #1a73e8;        /* Google blue 600 — the one primary action */
  --accent-dark: #1765cc;
  --danger: #d93025;        /* Google red 600 — missing artwork */
  --danger-bg: #fce8e6;
  --radius: 8px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font: 14px/1.5 Roboto, system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
  color: var(--fg);
  background: var(--bg);
}

/* ------------------------------------------------------------------ header */

.bar {
  position: sticky;
  top: 0;
  z-index: 10;
  padding: 14px 24px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

/* --------------------------------------------------------------- top nav bar */

/* Flat and square by design: no radius anywhere, one hairline underneath, and
   the smallest height the touch target allows. The current page is marked with
   a 2px underline rather than a filled pill. */
.topnav {
  display: flex;
  align-items: stretch;
  gap: 2px;
  padding: 0 24px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  /* Scrolls inside itself on a narrow screen. Without this the row pushes the
     document wider than the viewport and the whole page slides sideways. */
  overflow-x: auto;
  scrollbar-width: none;
}
.topnav::-webkit-scrollbar { display: none; }

.topnav-link,
.topnav-refresh {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px;
  min-height: 38px;
  border: none;
  border-radius: 0;
  background: none;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  /* Keeps the underline from shifting the row when it appears. */
  box-shadow: inset 0 -2px 0 transparent;
}

.topnav-link:hover,
.topnav-refresh:hover { background: var(--fill); color: var(--fg); }

.topnav-link:focus-visible,
.topnav-refresh:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.topnav-link[aria-current="page"] {
  color: var(--accent);
  box-shadow: inset 0 -2px 0 var(--accent);
}

/* Pushed to the end of the bar, per the nav spec. */
.topnav-refresh { margin-left: auto; color: var(--accent); }

/* On a phone the four items do not fit at full size. Tightening the spacing and
   dropping the Refresh wording — the icon and its aria-label carry it — keeps
   every item reachable without a sideways swipe. */
@media (max-width: 560px) {
  .topnav { padding: 0 12px; }
  .topnav-link, .topnav-refresh { padding: 0 9px; gap: 5px; }
  .topnav-refresh .btn-label { display: none; }
}

/* ------------------------------------------------------------------- icons */

/* Lucide ships 24x24 stroke icons; these two rules are all the alignment they
   need anywhere in the app. */
.icon { display: block; flex: none; }
[data-icon] { display: inline-flex; flex: none; }

.bar h1 { margin: 0 0 12px; font-size: 22px; font-weight: 400; }

.controls { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

/* The Drive/Gmail search pill: grey fill, no border, no label needed. */
.controls input[type="search"] {
  flex: 1 1 280px;
  max-width: 480px;
  font: inherit;
  padding: 9px 16px;
  border: 1px solid transparent;
  border-radius: 24px;
  background: var(--fill);
}
.controls input[type="search"]:focus {
  outline: none;
  background: #fff;
  border-color: var(--line);
  box-shadow: 0 1px 3px rgb(60 64 67 / .3);
}

/* Direct children only: the filter dropdowns nest their own buttons in here,
   and this selector outranks a lone class, so without the `>` it repaints the
   dropdown toggle and its Clear link — and the .active highlight below stops
   being visible at all. */
.controls > button {
  font: inherit;
  font-weight: 500;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #fff;
  color: var(--accent);
  cursor: pointer;
}
.controls > button:hover { background: var(--fill); }

/* ---------------------------------------------------------- filter dropdown */

/* A checkbox panel instead of a <select>, because every filter takes more than
   one value. The toggle keeps the old select's dimensions so the control row
   does not shift. */
.ms { position: relative; }

.ms-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  font: inherit;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #fff;
  color: var(--fg);
  cursor: pointer;
  max-width: 240px;
}
.ms-toggle:hover { background: var(--fill); }
.ms-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.ms-toggle[aria-expanded="true"] { border-color: var(--accent); }

/* A filter that is actually narrowing the grid says so, since the panel that
   would show you the ticks is closed most of the time. */
.ms-toggle.active { border-color: var(--accent); color: var(--accent); }

.ms-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ms-caret { flex: none; opacity: .7; }

.ms-panel {
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  left: 0;
  min-width: 240px;
  max-width: 320px;
  background: #fff;
  border-radius: var(--radius);
  box-shadow: 0 1px 2px rgb(60 64 67 / .3), 0 2px 6px 2px rgb(60 64 67 / .15);
  overflow: hidden;
}
.ms-panel[hidden] { display: none; }

.ms-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 14px 10px;
  border-bottom: 1px solid var(--line);
  font-size: 12px;
  color: var(--muted);
}

.ms-clear {
  font: inherit;
  font-weight: 500;
  padding: 0;
  border: none;
  background: none;
  color: var(--accent);
  cursor: pointer;
}
.ms-clear[hidden] { display: none; }

/* Fifty-six counties will not fit on screen, so the list scrolls and the header
   stays put. */
.ms-list { max-height: 300px; overflow-y: auto; padding: 6px 0; }

.ms-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 14px;
  font-size: 13px;
  cursor: pointer;
}
.ms-option:hover { background: var(--fill); }
.ms-option input {
  flex: none;
  width: 15px;
  height: 15px;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
}
.ms-option span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.ms-none { margin: 0; padding: 10px 14px; color: var(--muted); font-size: 13px; }

.status { margin: 10px 0 0; color: var(--muted); font-size: 12px; }
.status b { color: var(--fg); font-weight: 500; }
.status .flag-missing { color: var(--danger); font-weight: 500; }

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

main { padding: 8px 24px 48px; }

main h2 {
  margin: 28px 0 12px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .02em;
  text-transform: capitalize;
  color: var(--muted);
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 14px;
}

/* Flat until hovered, then it lifts — the Drive file-card behaviour. */
.card {
  display: flex;
  flex-direction: column;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
  cursor: pointer;
  overflow: hidden;
  text-align: left;
  font: inherit;
  transition: box-shadow .15s, border-color .15s;
}
.card:hover {
  border-color: transparent;
  box-shadow: 0 1px 2px rgb(60 64 67 / .3), 0 2px 6px 2px rgb(60 64 67 / .15);
}
.card:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.card img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--fill);
  display: block;
}

.card-body { padding: 8px 10px 10px; }
.card-title {
  display: block;
  font-size: 13px;
  font-weight: 500;
  /* Long generated slugs would otherwise stretch the whole grid. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.card-meta {
  display: block;
  font-size: 12px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A community with no artwork. Red is the whole point: this is a worklist. */
.card.missing { border-color: var(--danger); background: var(--danger-bg); }
.card.missing:hover { border-color: var(--danger); }
.card.missing .card-title { color: #b31412; }
.card.missing .card-meta { color: #c5221f; }

/* The placeholder that stands in for the picture that is not there. */
.no-image {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  aspect-ratio: 4 / 3;
  background: #f9dedc;
  color: #b31412;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .02em;
}

/* ------------------------------------------------------------------ badges */

.badge {
  display: inline-block;
  margin-top: 6px;
  padding: 1px 7px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 500;
}
.badge-missing { background: #f9dedc; color: #b31412; }
.badge-unlisted { background: var(--fill); color: var(--muted); }

/* ------------------------------------------------------------------- modal */

dialog {
  width: min(92vw, 1000px);
  padding: 0;
  border: none;
  border-radius: var(--radius);
  box-shadow: 0 11px 15px -7px rgb(60 64 67 / .2), 0 24px 38px 3px rgb(60 64 67 / .14);
}
dialog::backdrop { background: rgb(32 33 36 / .6); }

dialog img.hero { width: 100%; max-height: 66vh; object-fit: contain; background: #202124; display: block; }

.viewer-head { padding: 14px 16px 0; }
.viewer-head h3 { margin: 0; font-size: 18px; font-weight: 500; }
.viewer-head p { margin: 4px 0 0; color: var(--muted); font-size: 13px; }

.viewer-desc {
  margin: 10px 16px 0;
  padding: 10px 12px;
  background: var(--fill);
  border-radius: 4px;
  font-size: 13px;
  color: var(--fg);
}

.viewer-bar {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  padding: 14px 16px;
}

/* The URL sits in a read-only field: it makes the value obviously selectable,
   which is the manual path if Copy ever fails. */
.viewer-bar input {
  flex: 1 1 240px;
  min-width: 0;
  font: 12px/1.4 "Roboto Mono", ui-monospace, monospace;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--fill);
  color: var(--muted);
}

/* Google's two button grades: one filled primary, everything else plain text. */
.viewer-bar button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font: inherit;
  font-weight: 500;
  padding: 9px 16px;
  border: none;
  border-radius: 4px;
  background: none;
  color: var(--accent);
  cursor: pointer;
}
.viewer-bar button:hover { background: var(--fill); }
.viewer-bar .primary { background: var(--accent); color: #fff; }
.viewer-bar .primary:hover { background: var(--accent-dark); }
/* Copy is disabled on a community with no artwork; it should read that way. */
.viewer-bar button:disabled { color: var(--muted); background: var(--fill); cursor: default; }

.empty { color: var(--muted); }
.error { color: var(--danger); }
