/* Shared styles for /portfolio/ and its project pages. Tokens match the
   homepage's inline stylesheet so the two read as one site. */

@font-face { font-family: 'Roboto Slab'; src: url('/assets/fonts/roboto-slab-var.woff2') format('woff2'); font-weight: 100 900; font-style: normal; font-display: swap; }
@font-face { font-family: 'Spectral'; src: url('/assets/fonts/spectral-300.woff2') format('woff2'); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: 'Spectral'; src: url('/assets/fonts/spectral-400.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Spectral'; src: url('/assets/fonts/spectral-400-italic.woff2') format('woff2'); font-weight: 400; font-style: italic; font-display: swap; }

:root {
  --bg:        #020617;
  --surface:   #241735;
  --accent:    #7C3AED;   /* fills and borders; white-on-accent is 5.7:1 */
  --accent-text: #A78BFA; /* accent used AS text: 7.4:1, vs 3.5:1 for --accent */
  --soft:      #a98bd6;
  --tint:      #E9D9F2;
  --white:     #ffffff;

  --text:        #E9D9F2;
  --text-mid:    rgba(233, 217, 242, 0.82);
  --text-faint:  rgba(233, 217, 242, 0.62);
  --line:        rgba(169, 139, 214, 0.20);
  --line-strong: rgba(169, 139, 214, 0.40);

  --display: 'Roboto Slab', Georgia, 'Times New Roman', serif;
  --body:    'Spectral', Georgia, 'Times New Roman', serif;

  --gutter: 22px;
  --radius: 5px;
  --stack: 36px;   /* space between page sections */
  --ext-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 4h6v6M20 4l-9 9M18 14v6H4V6h6'/%3E%3C/svg%3E");
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  /* The glow behind the portrait sits on the body, which spans the full window.
     On the centered column it stopped at the column's edge on wide screens. */
  background: radial-gradient(ellipse 460px 320px at 50% 0, rgba(124, 58, 237, 0.34), rgba(2, 6, 23, 0) 74%) no-repeat var(--bg);
  color: var(--text);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
img, svg { display: block; max-width: 100%; height: auto; }
a { color: var(--soft); text-decoration: none; }
a:hover { color: var(--tint); }
a:focus-visible { outline: 3px solid var(--accent-text); outline-offset: 3px; border-radius: 2px; }
h1, h2, h3 { font-family: var(--display); color: var(--white); margin: 0; line-height: 1.2; text-wrap: balance; }
p { margin: 0; text-wrap: pretty; }
ul { list-style: none; margin: 0; padding: 0; }

/* The crystal sits behind everything, as on the homepage. */
body::before {
  content: "";
  position: fixed;
  top: -6vh;
  right: -22vw;
  width: min(115vw, 1000px);
  height: min(115vw, 1000px);
  background: url('/assets/crystal-bg.webp') no-repeat center / contain;
  mix-blend-mode: screen;
  opacity: 0.12;
  pointer-events: none;
  z-index: 0;
}
body > * { position: relative; z-index: 1; }

.wrap {
  max-width: 1120px; margin: 0 auto;
  padding: 20px var(--gutter) 48px;
  display: flex; flex-direction: column; gap: var(--stack);
}
main { display: flex; flex-direction: column; gap: var(--stack); }
.eyebrow {
  font-family: var(--display); font-weight: 600; font-size: 11px;
  letter-spacing: 0.26em; text-transform: uppercase; color: var(--accent-text);
}
.eyebrow a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.eyebrow a:hover { color: var(--tint); }
.section { display: flex; flex-direction: column; gap: 14px; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* Every link that opens a new tab carries the box-and-arrow mark. It is drawn
   as a mask so it takes the link's own colour; the words "opens in a new tab"
   are in the markup for screen readers. Tiles show it beside the name. */
a[target="_blank"]::after,
.tile[target="_blank"] .name::after,
.post[target="_blank"] .name::after {
  content: "";
  display: inline-block; flex: none;
  width: 0.72em; height: 0.72em; margin-left: 0.4em;
  background: currentColor;
  -webkit-mask: var(--ext-icon) no-repeat center / contain;
          mask: var(--ext-icon) no-repeat center / contain;
}
.tile[target="_blank"]::after, .post[target="_blank"]::after { content: none; }


/* Same header as giveaway.earlyspark.com: a small portrait that links home,
   with the name centered under it. */
.site-head { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.site-name { font-family: var(--display); font-weight: 600; font-size: 15px; line-height: 1.2; color: var(--white); }
.site-link { display: block; padding: 4px; border-radius: 999px; transition: background 140ms; }
.site-link img { width: 56px; height: 56px; border-radius: 50%; border: 1px solid var(--line); }
.site-link:hover { background: rgba(124, 58, 237, 0.24); }
.site-link:focus-visible { border-radius: 999px; }
.back { font-family: var(--display); font-size: 14px; min-height: 44px; display: flex; align-items: center; gap: 8px; align-self: flex-start; }
.back span { text-decoration: underline; text-underline-offset: 4px; }
.back svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* Breadcrumb trail above the page heading, set like the eyebrow on the
   giveaway page. The last item is the current page and is not a link. */
.crumb {
  font-family: var(--display); font-weight: 600; font-size: 12px;
  letter-spacing: 0.24em; text-transform: uppercase; color: var(--accent-text);
}
.crumb ol { display: flex; flex-wrap: wrap; align-items: center; gap: 0 10px; list-style: none; margin: 0; padding: 0; }
.crumb li + li::before { content: "/"; margin-right: 10px; }
.crumb a { color: inherit; display: inline-block; padding: 5px 0; text-decoration: underline; text-underline-offset: 3px; }
.crumb a:hover { color: var(--tint); }

.intro { display: flex; flex-direction: column; gap: 16px; }
/* Sized so the portfolio headline sits on one line from about 850px up and
   spans the same width as the paragraph under it. Balancing would stop it short. */
.intro h1 { font-size: clamp(28px, 3.3vw, 39px); font-weight: 700; letter-spacing: -0.015em; text-wrap: wrap; }
.lede { font-size: clamp(17px, 4.2vw, 20px); line-height: 1.55; color: var(--text-mid); }

.actions { display: flex; flex-wrap: wrap; gap: 10px; }
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 12px 20px;
  font-family: var(--display); font-weight: 600; font-size: 15px;
  border: 1px solid var(--line-strong); border-radius: 3px; color: var(--tint);
  transition: border-color 140ms, background 140ms;
}
.btn:hover { border-color: var(--accent); color: var(--white); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--white); }
.btn-primary:hover { background: #6d33d6; }

/* Featured case study: one wide card, image beside the copy from 640px up. */
.case {
  display: flex; flex-direction: column;
  border: 1px solid var(--line-strong); border-radius: 6px; overflow: hidden;
  background: linear-gradient(150deg, var(--surface) 0%, rgba(36, 23, 53, 0.48) 100%);
  color: var(--text);
  transition: border-color 140ms, transform 140ms;
}
.case:hover { border-color: var(--accent); color: var(--text); transform: translateY(-2px); }
.case img { width: 100%; border-bottom: 1px solid var(--line); }
.case-body { display: flex; flex-direction: column; gap: 10px; padding: 20px; min-width: 0; }
.case h3 { font-size: clamp(20px, 5.4vw, 26px); font-weight: 600; }
.case p { font-size: 16px; color: var(--text-mid); }
.case .more { font-family: var(--display); font-weight: 600; font-size: 15px; color: var(--accent-text); }
.tile .more { margin-top: auto; padding-top: 6px; font-family: var(--display); font-weight: 600; font-size: 14px; color: var(--accent-text); }
.tag { font-family: var(--display); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent-text); }
.stat { font-family: var(--display); font-weight: 600; color: var(--white); font-variant-numeric: tabular-nums; }

.tiles { display: grid; grid-template-columns: 1fr; gap: 10px; }
.tile {
  display: flex; flex-direction: column; gap: 5px;
  height: 100%; min-height: 44px; padding: 14px 16px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: rgba(36, 23, 53, 0.34);
  transition: border-color 140ms, transform 140ms, background 140ms;
}
.tile:hover { border-color: var(--accent); background: rgba(36, 23, 53, 0.6); transform: translateY(-2px); }
/* An informational tile, not a link: dashed outline, and it stays put on hover. */
.tile-note, .tile-note:hover { border-style: dashed; border-color: var(--line-strong); background: transparent; transform: none; }
.tile .name { font-family: var(--display); font-weight: 600; font-size: 15px; line-height: 1.25; color: var(--white); }
.tile .what { font-size: 13px; line-height: 1.45; }
/* Long hostnames exceed tile width at 375px and force horizontal scroll
   without this. */
.tile .name, .tile .what { overflow-wrap: anywhere; min-width: 0; }

/* Selected writing: a tile with the article's cover image on top and its
   publication date above the title. Covers are cropped to one shape so the
   row stays even whatever each image's own proportions are. */
.post {
  display: flex; flex-direction: column; height: 100%; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: rgba(36, 23, 53, 0.34);
  transition: border-color 140ms, transform 140ms, background 140ms;
}
.post:hover { border-color: var(--accent); background: rgba(36, 23, 53, 0.6); transform: translateY(-2px); }
.post img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-bottom: 1px solid var(--line); }
.post-body { display: flex; flex-direction: column; gap: 6px; padding: 14px 16px 16px; min-width: 0; }
/* Dates on every card: full date for articles, month and year for projects. */
.post time, .tile time, .case time { font-family: var(--display); font-size: 12px; letter-spacing: 0.04em; color: var(--text-faint); }
.post .name { font-family: var(--display); font-weight: 600; font-size: 15px; line-height: 1.3; color: var(--white); overflow-wrap: anywhere; }
.post .what { font-size: 13px; line-height: 1.45; }

/* Project page */
.facts { display: grid; grid-template-columns: 1fr; gap: 14px; margin: 0; }
.facts div { border-top: 1px solid var(--line); padding-top: 10px; min-width: 0; }
.facts dt { font-family: var(--display); font-weight: 600; font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent-text); }
.facts dd { margin: 4px 0 0; font-size: 15px; color: var(--text-mid); }
.facts a, .prose a { text-decoration: underline; text-underline-offset: 3px; }
.shot { margin: 0; display: flex; flex-direction: column; gap: 8px; }
.shot img { width: 100%; border: 1px solid var(--line); border-radius: 6px; }
.shot figcaption { font-size: 13px; color: var(--text-faint); }
.prose { display: flex; flex-direction: column; gap: 28px; }
.prose section { display: flex; flex-direction: column; gap: 10px; }
.prose h2 { font-size: clamp(20px, 5.2vw, 24px); font-weight: 600; }
.prose p, .prose li { font-size: clamp(16px, 4.1vw, 18px); line-height: 1.62; color: var(--text-mid); }
.prose ul { display: flex; flex-direction: column; gap: 10px; }
.prose li { position: relative; padding-left: 18px; }
.prose li::before { content: ""; position: absolute; left: 0; top: 0.8em; width: 8px; height: 1px; background: var(--soft); }
.prose strong { font-weight: 400; color: var(--white); }

.foot {
  padding-top: 28px; border-top: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 12px; align-items: center; text-align: center;
}
.mark { display: flex; align-items: center; gap: 13px; }
.mark img { width: 58px; height: 58px; }
.mark-text { display: flex; flex-direction: column; gap: 2px; text-align: left; }
.foot small { font-size: 13px; color: var(--text-faint); }

@media (min-width: 640px) {
  :root { --gutter: 34px; --stack: 48px; }
  .wrap { padding-top: 28px; }
  .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tile { padding: 18px; }
  .tile .name { font-size: 16px; }
  .case { flex-direction: row; align-items: stretch; }
  .case img { width: 54%; object-fit: cover; object-position: left center; border-bottom: 0; border-right: 1px solid var(--line); }
  .case-body { justify-content: center; padding: 28px; }
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 900px) {
  body { background: radial-gradient(ellipse 900px 460px at 50% 0, rgba(124, 58, 237, 0.32), rgba(2, 6, 23, 0) 76%) no-repeat var(--bg); }
  .tiles-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .tiles-4, .facts { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
