:root {
  --page-bg: #ffffff;
  --surface: #f4f8fb;
  --accent: #336699;
  --heading: #244a70;
  --on-accent: #ffffff;
  --text: #1a1a1a;
  --muted: #5a5a5a;
  --border: #d8e0e8;
  --link: #3d84c7;
}

@media (prefers-color-scheme: dark) {
  :root {
    --page-bg: #10161d;
    --surface: #1b2530;
    --accent: #336699;
    --heading: #8ec2f0;
    --on-accent: #ffffff;
    --text: #e6ecf1;
    --muted: #9fabb8;
    --border: #34404d;
    --link: #8ec2f0;
  }
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
  background-color: var(--page-bg);
  color: var(--text);
  font-family: -apple-system, "Segoe UI", Roboto, sans-serif;
  line-height: 1.5;
}

/* Page-wide default so any link renders consistently no matter which
   prose field it turns up in, not just the spots that got their own rule.
   The more specific link rules below (project-link, project-pdf-link, ...)
   still win where a bolder, more prominent treatment is wanted. */
a {
  color: var(--link);
  text-decoration: underline;
}

.portfolio-page {
  max-width: 1040px;
  margin: 0 auto;
  padding: 3rem 1.5rem 5rem;
}

@media (max-width: 420px) {
  .portfolio-page {
    padding: 2rem 1rem 3rem;
  }
}

.portfolio-title {
  color: var(--heading);
  font-size: 2rem;
  margin-bottom: 0.5rem;
}

.portfolio-intro {
  color: var(--muted);
  font-size: 1.05rem;
  margin-bottom: 1rem;
}

.portfolio-crosslinks {
  color: var(--muted);
  font-size: 0.9rem;
  margin: 0 0 2.5rem;
}

.portfolio-crosslinks a {
  color: var(--link);
  text-decoration: underline;
}

.project {
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  min-width: 0;
}

.project-header {
  width: 100%;
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  align-items: flex-start;
  gap: 0.5rem 1rem;
  background-color: var(--surface);
  color: var(--text);
  border: none;
  padding: 1rem 1.25rem;
  cursor: pointer;
  text-align: left;
  font: inherit;
}

.project.is-open .project-header {
  background-color: var(--accent);
  color: var(--on-accent);
}

.project-name {
  font-weight: 600;
  font-size: 1.05rem;
  min-width: 0;
}

.project-tags {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-content: flex-start;
  gap: 0.4rem;
  min-width: 0;
}

.tag-chip {
  /* Default fallback; actual per-tag colors are set inline via JS
     from TAG_COLORS in portfolio-data.js. */
  background-color: var(--accent);
  color: var(--on-accent);
  font-size: 0.75rem;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  white-space: nowrap;
}

/* Employer tags and the "lame grey" loadout tags stay hidden on the
   collapsed header - they're not the interesting part of the tag list
   at a glance - and only reveal once the project is expanded. */
.tag-chip-collapsed-hidden {
  display: none;
}

.project.is-open .tag-chip-collapsed-hidden {
  display: inline-block;
}

.project-body {
  display: none;
  padding: 1.25rem;
  border-top: 1px solid var(--border);
}

.project.is-open .project-body {
  display: block;
}

.project-attribution {
  font-weight: 600;
  color: var(--heading);
  margin: 0 0 0.75rem;
}

.project-description {
  margin: 0 0 1rem;
  color: var(--text);
}

/* --- Redaction stamps ---
   REDACTED_THINGS entries get swapped for one of these: the original text
   stays in the DOM (transparent, so it still reserves layout space and
   remains selectable) with an opaque black stamp positioned on top of it. */

.redacted {
  position: relative;
  display: inline-block;
}

.redacted-original {
  color: transparent;
}

.redacted-stamp {
  position: absolute;
  inset: -0.15em -0.4em;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #000;
  color: #fff;
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
  font-size: 0.66em;
  font-weight: 700;
  letter-spacing: 0.05em;
  white-space: nowrap;
  border-radius: 2px;
  pointer-events: none;
}

.project-media {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 1rem;
}

.project-video {
  max-width: 100%;
  border-radius: 6px;
  display: block;
}

/* Corner redaction stamp on a video (see redactCorner in portfolio.json):
   pinned to the top-left, clear of the native play button and control bar,
   and non-interactive so it never blocks a click on the video itself. */

.project-media-item {
  position: relative;
  display: inline-block;
  max-width: 100%;
}

.video-redacted-stamp {
  position: absolute;
  top: 0.65rem;
  left: -0.5rem;
  background-color: #000;
  color: #fff;
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
  font-size: 1.8rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  padding: 0.25rem 0.9rem;
  border-radius: 2px;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}

.project-pdf-link,
.project-link a {
  color: var(--link);
  font-weight: 600;
  text-decoration: underline;
}

/* --- Two-column layout --- */

/* --- Page layout ---
   Mobile-first: a single flex column, in DOM order (size toggle, then
   project list, then sidebar/tag filter). At the desktop breakpoint this
   switches to a real grid so the size toggle can visually relocate to the
   top of the sidebar column without moving it in the DOM (flexbox `order`
   only works within a single flex container, so a grid with named areas
   is what actually lets one element "jump" into a different visual
   column at a breakpoint). */

.portfolio-layout {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  min-width: 0;
}

#portfolio-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  min-width: 0;
}

.size-filter-mount {
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--border);
}

.portfolio-sidebar {
  min-width: 0;
}

@media (min-width: 701px) {
  .portfolio-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 280px;
    grid-template-rows: auto 1fr;
    column-gap: 2.5rem;
    row-gap: 1.5rem;
    grid-template-areas:
      "main size"
      "main sidebar";
    align-items: start;
  }

  .size-filter-mount {
    grid-area: size;
    padding-bottom: 1em;
    border-bottom: none;
  }

  #portfolio-list {
    grid-area: main;
  }

  .portfolio-sidebar {
    grid-area: sidebar;
  }
}

/* --- Size filter (big/small potato toggle) --- */

.size-filter {
  display: flex;
  gap: 0.75rem;
}

.size-chip {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  border: 1px solid var(--border);
  background-color: var(--surface);
  border-radius: 999px;
  padding: 0.4rem 0.9rem 0.4rem 0.6rem;
  cursor: pointer;
  font: inherit;
  font-size: 0.9rem;
  color: var(--text);
  transition: opacity 0.15s ease;
}

.size-chip.is-active {
  background-color: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

.size-chip.is-muted {
  opacity: 0.4;
}

.size-icon {
  display: inline-flex;
  color: var(--heading);
}

.size-chip.is-active .size-icon {
  color: var(--on-accent);
}

.size-icon svg {
  display: block;
}

.size-icon-big svg {
  width: 1.6rem;
  height: 1rem;
}

.size-icon-small svg {
  width: 0.9rem;
  height: 0.56rem;
}

/* --- Tag filter (cloud + legend) --- */

.tag-filter {
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

.tag-filter-group {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.tag-filter-group-heading-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}

.tag-filter-group-heading {
  margin: 0;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}

.tag-legend-toggle {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 0.7rem;
  font-style: italic;
  color: var(--muted);
  cursor: pointer;
  text-decoration: underline;
  white-space: nowrap;
}

.tag-legend-toggle:hover {
  color: var(--heading);
}

.tag-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.tag-cloud-chip {
  border: none;
  border-radius: 999px;
  padding: 0.3rem 0.75rem;
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
  transition: opacity 0.15s ease, box-shadow 0.15s ease;
  /* Default fallback; actual per-tag colors are set inline via JS. */
  background-color: var(--accent);
  color: var(--on-accent);
}

.tag-cloud-chip.is-active {
  box-shadow: 0 0 0 2px var(--heading);
}

.tag-cloud-chip.is-muted {
  opacity: 0.3;
}

.tag-legend {
  margin: 0;
  display: none;
  flex-direction: column;
  gap: 0.6rem;
  font-size: 0.82rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

.tag-legend.is-visible {
  display: flex;
}

.tag-legend-row {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  cursor: pointer;
  border-radius: 4px;
  padding: 0.25rem 0.3rem;
  transition: opacity 0.15s ease, background-color 0.15s ease;
}

.tag-legend-row:hover {
  background-color: var(--surface);
}

.tag-legend-row.is-active {
  background-color: var(--surface);
  box-shadow: inset 2px 0 0 var(--heading);
}

.tag-legend-row.is-muted {
  opacity: 0.4;
}

.tag-legend-term {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
  color: var(--heading);
}

.tag-legend-swatch {
  display: inline-block;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  flex-shrink: 0;
}

.tag-legend-description {
  margin: 0 0 0 1.1rem;
  color: var(--muted);
}

/* --- Narrow phone tightening ---
   Placed at the end of the file so these overrides reliably win the
   cascade against their base rules (same selector, same specificity,
   later source order wins when a media query's condition is active). */

@media (max-width: 420px) {
  .project-header {
    padding: 0.85rem 1rem;
  }
}
