/* ==========================================================================
   Cedric Chang portfolio
   Palette, type and imagery rules come from the brand guide in Brand Assets/.
   One accent across the whole site, carried on a tonal ramp. Light and dark.
   ========================================================================== */

:root {
  color-scheme: light dark;

  --ink: #201f1d;
  --ink-soft: #56514c;
  --ink-faint: #6f6862;
  --rule: #d7d3d3;
  --paper: #f3f2f2;
  --paper-2: #e9e7e6;

  /* One orange, four jobs. --accent draws rules and marks. --accent-text and
     --accent-fill are the darker step, because the brand orange only reaches
     about 4.2:1 against paper either as text or as a ground under white, and
     the labels sitting on it are small. --accent-ink goes on top of a fill. */
  --accent: #d35400;
  --accent-text: #a03d00;
  --accent-fill: #a03d00;
  --accent-hover: #a03d00;
  --accent-ink: #ffffff;

  --danger: #b02a1f;

  --display: "Bitter", Georgia, "Times New Roman", serif;
  --body: "Lora", Georgia, "Times New Roman", serif;
  --util: "Lora", Georgia, "Times New Roman", serif;

  --gutter: clamp(1.25rem, 5vw, 5rem);
  --stack: clamp(3.5rem, 8vw, 7rem);
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #f2efe9;
    --ink-soft: #b9b2a9;
    --ink-faint: #8b847b;
    --rule: #3a3632;
    --paper: #1c1a18;
    --paper-2: #262320;

    --accent: #ff8c42;
    --accent-text: #ff8c42;
    --accent-fill: #ff8c42;
    --accent-hover: #ffab6b;
    --accent-ink: #1c1a18;

    --danger: #ff7d6e;
  }
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
}

/* --------------------------------------------------------------- type ---- */

/* Bitter is a slab. It does not want the tight tracking a grotesk does, so the
   letter-spacing here is far gentler than a sans would take. */
h1,
h2,
h3 {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.1;
  margin: 0;
}

h1 {
  font-size: clamp(2.5rem, 7vw, 5.25rem);
  font-weight: 800;
}

h2 {
  font-size: clamp(1.875rem, 4vw, 2.875rem);
}

h3 {
  font-size: clamp(1.25rem, 2vw, 1.625rem);
  letter-spacing: -0.01em;
}

p {
  margin: 0 0 1.1em;
  max-width: 62ch;
}

.eyebrow {
  font-family: var(--util);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 1.25rem;
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.eyebrow::before {
  content: "";
  width: 1.75rem;
  height: 2px;
  background: var(--accent);
  flex: none;
}

.lede {
  font-size: clamp(1.125rem, 1.7vw, 1.375rem);
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 46ch;
}

/* ------------------------------------------------------------ skip link -- */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: var(--paper);
  padding: 0.75rem 1rem;
  z-index: 100;
}

.skip:focus {
  left: 0;
}

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

/* ---------------------------------------------------------------- nav ---- */

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.5rem var(--gutter);
  border-bottom: 1px solid var(--rule);
  flex-wrap: wrap;
  position: sticky;
  top: 0;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(10px);
  z-index: 40;
}

/* Name over role, flush left. Per the brand guide the wordmark is never bolded
   further, condensed, or set in caps, so this is the only treatment it gets. */
.wordmark {
  display: block;
  text-decoration: none;
  line-height: 1.15;
}

.wordmark__name {
  display: block;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.625rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.masthead nav {
  display: flex;
  gap: 1.5rem;
  font-family: var(--util);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.masthead nav a {
  text-decoration: none;
  color: var(--ink-soft);
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s;
}

.masthead nav a:hover {
  color: var(--ink);
  border-color: var(--accent);
}

.masthead nav a[aria-current="page"] {
  color: var(--ink);
  border-color: var(--accent);
}

/* ------------------------------------------------------------- layout ---- */

.wrap {
  padding: var(--stack) var(--gutter);
  max-width: 78rem;
  margin: 0 auto;
}

.wrap--tight {
  max-width: 52rem;
}

.rule {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 0;
}

/* ========================================================== landing page == */

.hero {
  padding: clamp(4rem, 12vw, 9rem) var(--gutter) clamp(3rem, 7vw, 5rem);
  max-width: 78rem;
  margin: 0 auto;
}

.hero h1 {
  max-width: 14ch;
}

.hero h1 em {
  font-style: normal;
  display: block;
  color: var(--ink-faint);
}

.hero .lede {
  margin-top: 1.75rem;
}

/* ------------------------------------------------------------- ticker ---- */

.strip {
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: 1.5rem var(--gutter);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem 2.5rem;
  font-family: var(--util);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  max-width: 78rem;
  margin: 0 auto;
}

/* -------------------------------------------------------- project nav ---- */

.project-nav-group {
  border-top: 1px solid var(--rule);
  background: var(--paper-2);
  padding: 1.25rem var(--gutter) 1.5rem;
}

.project-nav-group + .project-nav-group {
  border-top: none;
}

.project-nav-group:last-of-type {
  border-bottom: 1px solid var(--rule);
}

.project-nav-group__label {
  display: block;
  text-align: center;
  font-family: var(--util);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.75rem;
}

.project-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
}

.project-nav button {
  font-family: var(--util);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 0.7rem 1.4rem;
  background: var(--paper);
  color: var(--ink-soft);
  border: 1px solid var(--rule);
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.project-nav button:hover {
  border-color: var(--accent);
  color: var(--ink);
}

.project-nav button[aria-selected="true"] {
  background: var(--accent-fill);
  color: var(--accent-ink);
  border-color: var(--accent-fill);
}

/* ============================================================ work items == */

.work {
  border-top: 1px solid var(--rule);
  padding-top: clamp(2rem, 4vw, 3.5rem);
  margin-top: clamp(2.5rem, 5vw, 4.5rem);
}

.work:first-of-type {
  margin-top: 0;
}

.work[data-project] {
  display: none;
}

.work[data-project].is-active {
  display: block;
}

.work__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: start;
  margin-bottom: 2.25rem;
}

.work__meta {
  font-family: var(--util);
  font-size: 0.75rem;
  line-height: 1.9;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  list-style: none;
  padding: 0;
  margin: 1.25rem 0 0;
}

.work__meta b {
  color: var(--ink);
  font-weight: 500;
}

/* Category kicker on every project card. Uses the darker accent step because it
   is small text on paper. */
.tag {
  display: inline-block;
  font-family: var(--util);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.25rem 0.6rem;
  border: 1px solid var(--accent);
  color: var(--accent-text);
  margin-bottom: 1rem;
}

.tag--quiet {
  border-color: var(--rule);
  color: var(--ink-faint);
}

/* ------------------------------------------------------------- embeds ---- */

.embed {
  border: 1px solid var(--rule);
  background: var(--paper-2);
  margin-bottom: 1.75rem;
}

.embed__bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 0.6rem 0.9rem;
  border-bottom: 1px solid var(--rule);
  font-family: var(--util);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.embed__bar a {
  color: var(--accent-text);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}

.embed__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
}

.embed__frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* itch player is usually 4:3-ish. Override per project if you need to. */
.embed__frame--itch {
  aspect-ratio: 4 / 3;
}

.embed__launch {
  position: absolute;
  inset: 0;
  margin: auto;
  width: fit-content;
  height: fit-content;
  padding: 0.75rem 1.5rem;
  background: var(--accent-fill);
  color: var(--accent-ink);
  border: 0;
  font-family: var(--util);
  font-size: 0.8125rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
}

.embed__launch:hover {
  filter: brightness(1.1);
}

/* ------------------------------------------------------------ carousel --- */

.shots {
  position: relative;
}

.shots__track {
  display: flex;
  gap: 0.75rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding-bottom: 0.75rem;
  scrollbar-width: thin;
}

.shots__track figure {
  margin: 0;
  flex: 0 0 min(34rem, 82%);
  scroll-snap-align: start;
}

/* The mat. Padding on the image itself puts the surface color in a band around
   the picture, which is the border treatment the brand guide asks for on every
   project thumbnail and on the headshot. */
.shots__track img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border: 1px solid var(--rule);
  background: var(--paper-2);
  padding: clamp(0.4rem, 0.9vw, 0.7rem);
  cursor: zoom-in;
}

.shots__track figcaption {
  font-family: var(--util);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  padding-top: 0.6rem;
}

.shots__nav {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.shots__nav button {
  font-family: var(--util);
  font-size: 0.875rem;
  line-height: 1;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid var(--rule);
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}

.shots__nav button:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}

.shots__nav button:disabled {
  opacity: 0.3;
  cursor: default;
}

/* ------------------------------------------------------------ lightbox --- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(1.5rem, 6vw, 4rem);
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.lightbox[hidden] {
  display: none;
}

.lightbox__img {
  max-width: 100%;
  max-height: 100%;
  border: 1px solid var(--rule);
  background: var(--paper-2);
}

.lightbox__close {
  position: fixed;
  top: clamp(0.75rem, 3vw, 1.5rem);
  right: clamp(0.75rem, 3vw, 1.5rem);
  width: 2.5rem;
  height: 2.5rem;
  font-size: 1.5rem;
  line-height: 1;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--rule);
  cursor: pointer;
}

.lightbox__close:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* ------------------------------------------------------------ portrait --- */
/* Same mat as the project thumbnails, plus the warm archival grade the brand
   guide specifies. The crop is framed on the face, not on the center of the
   file, which is why object-position sits off to the right. */

.portrait {
  margin: 0;
  width: 100%;
  max-width: 17rem;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  padding: clamp(0.4rem, 0.9vw, 0.7rem);
}

.portrait img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  object-position: 62% 50%;
  filter: sepia(0.22) saturate(0.82) contrast(1.05);
}

.bio {
  display: grid;
  grid-template-columns: minmax(0, 17rem) minmax(0, 1fr);
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: start;
}

.bio__aside {
  display: flex;
  flex-direction: column;
}

.bio__resume {
  width: 100%;
  box-sizing: border-box;
  margin-top: 1rem;
}

.bio p:last-child {
  margin-bottom: 0;
}

@media (max-width: 46rem) {
  .bio {
    grid-template-columns: 1fr;
  }

  .portrait {
    max-width: 12rem;
  }
}

/* ============================================================== columns == */

.cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: clamp(1.5rem, 3vw, 2.75rem);
}

.card {
  border-top: 2px solid var(--accent);
  padding-top: 1.25rem;
}

.card h3 {
  margin-bottom: 0.6rem;
}

.card p {
  font-size: 0.9375rem;
  color: var(--ink-soft);
  margin-bottom: 0;
}

.note {
  font-size: 0.875rem;
  color: var(--ink-faint);
  border-left: 2px solid var(--rule);
  padding-left: 1rem;
  max-width: 52ch;
}

/* ================================================================= form == */

.form {
  display: grid;
  gap: 1.5rem;
  max-width: 40rem;
}

.field {
  display: grid;
  gap: 0.4rem;
}

.field label,
.fieldset legend {
  font-family: var(--util);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.field input,
.field select,
.field textarea {
  font-family: var(--body);
  font-size: 1rem;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--ink);
  border-radius: 0;
  padding: 0.75rem 0.85rem;
  width: 100%;
  transition: border-color 0.15s;
}

.field textarea {
  min-height: 7rem;
  resize: vertical;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--accent);
}

.field .hint {
  font-size: 0.8125rem;
  color: var(--ink-faint);
}

.fieldset {
  border: 0;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.6rem;
}

.choice {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.choice label {
  flex: 1 1 12rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  border: 1px solid var(--rule);
  padding: 0.8rem 1rem;
  cursor: pointer;
  font-family: var(--body);
  font-size: 0.9375rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  transition: border-color 0.15s, background 0.15s;
}

.choice label:hover {
  border-color: var(--accent);
}

.choice input {
  accent-color: var(--accent);
  width: auto;
  margin: 0;
}

.choice input:checked + span {
  font-weight: 600;
}

/* Used as both <button> and <a>, so it has to carry its own display and
   text-decoration rather than relying on the element. */
.btn {
  font-family: var(--util);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  background: var(--accent-fill);
  color: var(--accent-ink);
  border: 1px solid var(--accent-fill);
  padding: 1rem 2rem;
  cursor: pointer;
  justify-self: start;
  display: inline-block;
  text-align: center;
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
}

.btn:hover {
  background: transparent;
  color: var(--accent-text);
  border-color: var(--accent-hover);
}

.btn--ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--ink);
}

.btn--ghost:hover {
  background: var(--ink);
  color: var(--paper);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.875rem;
  margin-top: 2.25rem;
}


.form__status {
  font-family: var(--util);
  font-size: 0.8125rem;
  padding: 0.9rem 1rem;
  border: 1px solid var(--rule);
}

.form__status[data-state="ok"] {
  border-color: var(--accent);
  color: var(--accent-text);
}

.form__status[data-state="err"] {
  border-color: var(--danger);
  color: var(--danger);
}

.form__status[hidden] {
  display: none;
}

/* =============================================================== footer == */

.footer {
  border-top: 1px solid var(--rule);
  padding: clamp(2.5rem, 5vw, 4rem) var(--gutter);
  display: flex;
  justify-content: center;
  font-family: var(--util);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
}

.footer__social {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
}

.footer__social .btn {
  padding: 0.75rem 1.25rem;
}

/* ============================================================ responsive == */

@media (max-width: 46rem) {
  .work__head {
    grid-template-columns: 1fr;
  }

  .masthead {
    position: static;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }

  .shots__track {
    scroll-behavior: auto;
  }
}
