/* ============================================================
   Radiance Haus — typography site v1
   Palette HEX values are authoritative (Notion: 01.03 Existing
   Branding Elements). Headers: Oswald SemiBold. Body: Inter.
   ============================================================ */

:root {
  --parchment:   #FCF6F0;
  --shadow:      #24212A;
  --sandy:       #F89C49;
  --coral:       #F26C73;
  --amethyst:    #A27BB7;
  --french-blue: #413D7B;

  --font-display: "Oswald", "Arial Narrow", sans-serif;
  --font-body: "Inter", "Helvetica Neue", sans-serif;

  /* Fluid type scale */
  --step-hero:  clamp(3rem, 11vw, 9.5rem);
  --step-xl:    clamp(1.8rem, 4.5vw, 3.4rem);
  --step-lg:    clamp(1.6rem, 4vw, 2.8rem);
  --step-md:    clamp(1.1rem, 2.2vw, 1.5rem);
  --step-sm:    clamp(0.85rem, 1.4vw, 1rem);
}

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

html { scroll-behavior: smooth; }

body {
  font-family: var(--font-body);
  font-weight: 400;
  background: var(--sandy);
  color: var(--shadow);
  text-transform: uppercase;
  -webkit-font-smoothing: antialiased;
}

::selection {
  background: var(--shadow);
  color: var(--sandy);
}

/* ---------- Hero ---------- */

/* min-height is declared twice on purpose: svh is the "small" viewport, the
   height with the mobile address bar showing. Browsers that don't know svh
   ignore the second line and keep the vh behaviour. Without it, iOS Safari
   measures 92vh against the *tallest* viewport and clips the hero as the
   address bar collapses. */
.hero {
  position: relative;
  overflow: hidden;
  min-height: 92vh;
  min-height: 92svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 4rem 6vw;
  background: var(--sandy);
}

/* Starburst watermark: the SVG is centered on the burst itself, so the
   default 50%/50% transform origin keeps the center pinned to the
   hero's bottom-right corner. Only the top-left quadrant shows.
   Stationary, held at a 20° tilt. */
.hero-burst {
  position: absolute;
  width: 288vmin;
  height: auto;
  right: -144vmin;
  bottom: -144vmin;
  opacity: 0.18;
  pointer-events: none;
  z-index: 1;
  rotate: 20deg;
}

.hero > *:not(.hero-burst) {
  position: relative;
  z-index: 2;
}

.wordmark {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-hero);
  line-height: 0.95;
  letter-spacing: -0.01em;
  color: var(--shadow);
}

.wordmark-line { display: block; }

.wordmark-line:last-child { color: var(--french-blue); }

.tagline {
  margin-top: 2.5rem;
  font-size: var(--step-md);
  font-weight: 500;
  letter-spacing: 0.14em;
  color: var(--shadow);
}

.tagline em {
  font-style: normal;
  color: var(--french-blue);
}

/* ---------- Thesis (the one dark moment) ---------- */

.thesis {
  background: var(--shadow);
  color: var(--parchment);
  padding: 18vh 6vw;
}

.thesis-copy {
  font-family: "General Sans", var(--font-body);
  font-weight: 400;
  font-size: var(--step-md);
  line-height: 1.6;
  text-transform: none;
  text-align: right;
  max-width: 56ch;
  margin-left: auto;
  border-right: 0.35rem solid var(--parchment);
  padding-right: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}

/* ---------- About ---------- */

.about {
  background: var(--parchment);
  padding: 18vh 6vw;
  display: flex;
  flex-direction: column;
  gap: 4rem;
}

/* Portfolio selection list */
.services {
  list-style: none;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  gap: 0.4rem;
}

.services li {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(3.5rem, 10.5vw, 8rem);
  line-height: 1.05;
  letter-spacing: 0.01em;
  color: var(--item-color);
}

.services li a {
  color: inherit;
  text-decoration: none;
  transition: color 160ms ease;
}

/* Rotate through the brand palette (Parchment is the section
   background; Shadow is reserved for the hover state) */
.services li:nth-child(4n+1) { --item-color: var(--coral); }
.services li:nth-child(4n+2) { --item-color: var(--amethyst); }
.services li:nth-child(4n+3) { --item-color: var(--french-blue); }
.services li:nth-child(4n+4) { --item-color: var(--sandy); }

/* Hover: Parchment fill, thick outline in the item's rotation colour.
   Keyboard focus gets it unconditionally. Hover is gated behind a real
   pointer, because on a touch screen :hover latches on after a tap and
   stays stuck until you tap something else. */
.services li a:focus-visible {
  color: var(--parchment);
  -webkit-text-stroke: 6px var(--item-color);
  paint-order: stroke fill;
}

@media (hover: hover) and (pointer: fine) {
  .services li a:hover {
    color: var(--parchment);
    -webkit-text-stroke: 6px var(--item-color);
    paint-order: stroke fill;
  }
}

/* ---------- Mission band ---------- */

/* The mission sits in its own French Blue band; the invitation below it gets
   a Parchment band of its own. The 5rem bottom margin that used to separate
   the two is gone — the band padding does that job now. */
.mission-band {
  background: var(--french-blue);
  color: var(--parchment);
  padding: 16vh 6vw;
}

.contact-mission {
  font-size: var(--step-md);
  line-height: 1.5;
  letter-spacing: 0.04em;
  max-width: 44ch;
  margin: 0 0 0 auto;
  text-align: justify;
  text-align-last: right;
  border-right: 0.35rem solid var(--sandy);
  padding-right: 1.5rem;
  color: var(--parchment);
}

/* ---------- Contact ---------- */

/* Parchment band. Sandy on Parchment is far too low-contrast to read, so the
   prompt takes French Blue and the address takes Shadow; Coral stays the
   hover colour, as it is everywhere else on the site. */
.contact {
  background: var(--parchment);
  color: var(--shadow);
  padding: 16vh 6vw;
  text-align: center;
}

.contact-prompt {
  font-size: var(--step-md);
  font-weight: 500;
  letter-spacing: 0.14em;
  margin-bottom: 2rem;
  color: var(--french-blue);
}

.contact-email {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-xl);
  color: var(--shadow);
  text-decoration: none;
  border-bottom: 0.15em solid transparent;
  transition: color 160ms ease, border-color 160ms ease;
}

.contact-email:hover,
.contact-email:focus-visible {
  color: var(--coral);
  border-bottom-color: var(--coral);
}

/* ---------- Footer ---------- */

.footer {
  display: flex;
  flex-direction: column;
  gap: 2.5rem;
  padding: 3.5rem 6vw 2.5rem;
  font-size: var(--step-sm);
  font-weight: 500;
  letter-spacing: 0.1em;
}

/* The Acknowledgement of Country is set in sentence case rather than the
   site-wide uppercase. It is a formal statement of respect and several
   sentences long; all-caps would make it both harder to read and louder in
   tone than it should be. The thesis copy opts out the same way. */
.footer-acknowledgement {
  font-family: "General Sans", var(--font-body);
  font-weight: 400;
  font-size: var(--step-sm);
  line-height: 1.65;
  letter-spacing: 0;
  text-transform: none;
  max-width: 70ch;
}

.footer-locations {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  color: var(--french-blue);
}

.footer-meta {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem 2rem;
}

.footer-tagline { color: var(--french-blue); }

/* ---------- Tablet and below ---------- */

/* The service names wrap onto two, three or four lines at these widths. With
   the desktop 0.4rem gap, the space between two wrapped lines of ONE service
   is the same as the space between two different services, so all five run
   together as a single block of type. Opening the gap and tightening the
   leading pushes them apart from both directions: a wrapped line clearly
   belongs to the name above it, and a new name clearly starts a new group.
   Desktop keeps its tuned spacing. */
@media (max-width: 1024px) {
  .services { gap: 2.25rem; }
  .services li { line-height: 0.95; }
}

/* ---------- Small screens ---------- */

@media (max-width: 600px) {
  /* "ARCHITECTURE" is 6.14x the font size wide in Oswald SemiBold, and the
     usable column is 88vw, so anything above 88/6.14 = 14.3vw overflows.
     At the old fixed 3.5rem floor the page scrolled sideways on every phone
     narrower than ~366px, which includes the standard 360px Android width.
     The 3.5rem ceiling here is that same old value, so this is a no-op at
     400px and wider and only rescues the widths that were broken. */
  .services li {
    font-size: clamp(2.25rem, 14vw, 3.5rem);
  }

  /* 0.14em tracking pushed "US." onto a line of its own. */
  .contact-prompt {
    letter-spacing: 0.08em;
  }

  .tagline {
    font-size: clamp(0.65rem, 3.2vw, 1rem);
    letter-spacing: 0.05em;
    line-height: 1.6;
    max-width: 100%;
    white-space: normal;
    overflow-wrap: break-word;
  }

  .contact-mission {
    margin-left: 0;
    text-align: left;
    text-align-last: left;
    border-right: none;
    border-left: 0.35rem solid var(--sandy);
    padding-right: 0;
    padding-left: 1.5rem;
  }

  .thesis-copy {
    max-width: 100%;
    text-align: left;
    border-right: none;
    border-left: 0.35rem solid var(--parchment);
    padding-right: 0;
    padding-left: 1.5rem;
    margin-left: 0;
  }

  .contact-email {
    font-size: clamp(1.4rem, 7vw, 2.2rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .contact-email { transition: none; }
  .services li a { transition: none; }
  .portfolio-back,
  .login-submit,
  .admin-upload-btn,
  .admin-logout { transition: none; }
}

/* ---------- Portfolio pages ---------- */

.portfolio-page { background: var(--parchment); }

.portfolio-hero {
  padding: 10vh 6vw 6vh;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

.portfolio-back {
  font-size: var(--step-sm);
  font-weight: 500;
  letter-spacing: 0.14em;
  color: var(--french-blue);
  text-decoration: none;
  align-self: flex-start;
  border-bottom: 0.12em solid transparent;
  transition: color 160ms ease, border-color 160ms ease;
}

.portfolio-back:hover,
.portfolio-back:focus-visible {
  color: var(--coral);
  border-bottom-color: var(--coral);
}

.portfolio-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.8rem, 8vw, 6rem);
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--shadow);
}

.gallery { padding: 0 6vw 14vh; }

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
  gap: 1.5rem;
}

.gallery-item {
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: color-mix(in srgb, var(--shadow) 8%, var(--parchment));
}

.gallery-item img,
.gallery-item video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.gallery-file-link {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: 1rem;
  text-align: center;
  font-size: var(--step-sm);
  letter-spacing: 0.06em;
  color: var(--french-blue);
}

.gallery-status {
  margin-top: 2.5rem;
  font-size: var(--step-sm);
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--french-blue);
}

/* ---------- Login gate ---------- */

/* Two horizontal bands, the same rhythm the landing page uses: the brand face
   on Sandy, the form on a calm Parchment surface below it. The logo lockup
   already carries the starburst, so there is deliberately no burst watermark
   behind it — two bursts at similar scale compete instead of reinforcing. */
.login-page { background: var(--sandy); }

.login-main {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

.login-brand {
  background: var(--sandy);
  padding: 9vh 6vw 7vh;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.75rem;
}

/* The width lives on the wrapper, not the image. .login-brand is a flex column
   with align-items: flex-start, so the heading shrinks to fit its content —
   a percentage width on the image would resolve against the image's own
   intrinsic 300px and never grow. line-height 0 removes the descender gap
   under the inline image. */
.login-logo-wrap {
  line-height: 0;
  width: min(100%, 30rem);
}

.login-logo {
  display: block;
  width: 100%;
  height: auto;
}

.login-brand-note {
  font-size: var(--step-sm);
  font-weight: 500;
  letter-spacing: 0.14em;
  color: var(--shadow);
}

.login-brand-note em {
  font-style: normal;
  color: var(--french-blue);
}

.login-panel {
  flex: 1;
  background: var(--parchment);
  padding: 8vh 6vw;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.login-form {
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
  width: 100%;
  max-width: 26rem;
}

.login-intro {
  font-size: var(--step-sm);
  font-weight: 500;
  letter-spacing: 0.12em;
  color: var(--french-blue);
}

.login-field {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.login-label {
  font-size: var(--step-sm);
  font-weight: 500;
  letter-spacing: 0.14em;
}

.login-input {
  font: inherit;
  font-size: 1.1rem;
  text-transform: none;
  padding: 0.9rem 1rem;
  border: 0.15rem solid var(--shadow);
  background: var(--parchment);
  color: var(--shadow);
}

.login-input:focus-visible {
  outline: 0.2rem solid var(--french-blue);
  outline-offset: 0.1rem;
}

.login-submit {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.4rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0.8rem 1rem;
  border: none;
  background: var(--shadow);
  color: var(--sandy);
  cursor: pointer;
  transition: background 160ms ease;
}

.login-submit:hover,
.login-submit:focus-visible { background: var(--french-blue); }

.login-error {
  font-size: var(--step-sm);
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--shadow);
  border-left: 0.35rem solid var(--coral);
  padding-left: 1rem;
}

/* ---------- Admin ---------- */

.admin-page { background: var(--parchment); }

.admin-main {
  max-width: 46rem;
  margin: 0 auto;
  padding: 10vh 6vw;
  display: flex;
  flex-direction: column;
  gap: 4rem;
}

.admin-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 1rem 2rem;
}

.admin-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-xl);
  color: var(--shadow);
}

.admin-subtitle {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-md);
  margin-bottom: 1.5rem;
  color: var(--shadow);
}

.admin-upload { display: flex; flex-direction: column; gap: 1rem; }

.admin-label {
  font-size: var(--step-sm);
  font-weight: 500;
  letter-spacing: 0.1em;
  margin-top: 0.5rem;
}

.admin-select,
.admin-file-input {
  font: inherit;
  font-size: 1rem;
  text-transform: none;
  padding: 0.7rem 0.9rem;
  border: 0.15rem solid var(--shadow);
  background: var(--parchment);
  color: var(--shadow);
}

.admin-upload-btn,
.admin-logout {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border: none;
  cursor: pointer;
  background: var(--shadow);
  color: var(--parchment);
  transition: background 160ms ease;
}

.admin-upload-btn { font-size: 1.2rem; padding: 0.7rem 1rem; margin-top: 0.5rem; }
.admin-logout { font-size: 1rem; padding: 0.5rem 0.9rem; white-space: nowrap; }

.admin-upload-btn:hover,
.admin-upload-btn:focus-visible,
.admin-logout:hover,
.admin-logout:focus-visible { background: var(--french-blue); }

.admin-upload-btn:disabled { opacity: 0.5; cursor: wait; }

.admin-status {
  font-size: var(--step-sm);
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--french-blue);
}

.admin-file-list { list-style: none; }

.admin-file-row {
  display: flex;
  align-items: baseline;
  gap: 1.5rem;
  padding: 0.8rem 0;
  border-bottom: 1px solid color-mix(in srgb, var(--shadow) 20%, var(--parchment));
}

.admin-file-name {
  flex: 1;
  text-transform: none;
  font-size: 1rem;
  overflow-wrap: anywhere;
}

.admin-file-meta {
  font-size: var(--step-sm);
  color: var(--french-blue);
  white-space: nowrap;
}

.admin-delete {
  font: inherit;
  font-size: var(--step-sm);
  font-weight: 600;
  letter-spacing: 0.08em;
  border: none;
  background: none;
  color: var(--coral);
  cursor: pointer;
  padding: 0;
}

.admin-delete:hover,
.admin-delete:focus-visible { color: var(--shadow); }

/* On a phone the filename, its size and the delete control crush together on
   one line. Give the name the full width and let the other two sit under it. */
@media (max-width: 480px) {
  .admin-file-row {
    flex-wrap: wrap;
    gap: 0.35rem 1rem;
  }

  .admin-file-name { flex: 1 0 100%; }
}
