/* Investor-facing pages: landing and case studies.
   Deliberately drops the cursor, orbs, scan line and star field from
   shared.css. The app and Maven pages keep shared.css and their character. */

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

:root {
  --y:      #FFD600;
  --bg:     #05050A;
  --border: rgba(255,255,255,0.09);
  --text:   #F0F0F0;
  --muted:  rgba(240,240,240,0.65);
  --dim:    rgba(240,240,240,0.38);
  --sans: 'Space Grotesk', system-ui, sans-serif;
  --mono: 'Space Mono', ui-monospace, Consolas, monospace;
}

html { min-height: 100%; }

/* ── SELECTION ──
   Off by default: these are presentation surfaces, and a stray blue drag
   selection cheapens them. Anything a reader has an actual reason to copy opts
   back in: the contact address, and code or samples if any ever appear here. */
:root { -webkit-user-select: none; -moz-user-select: none; user-select: none; }

a[href^="mailto:"],
pre, code, kbd, samp,
input, textarea,
[data-copyable] {
  -webkit-user-select: text;
  -moz-user-select: text;
  user-select: text;
}

/* ── STAR FIELD ──
   Canvas painted by stars.js, sitting behind the page. Same field as the app and
   Maven pages, without the rest of shared.css. */
#stars { position: fixed; inset: 0; z-index: 0; pointer-events: none; }

/* ── CURSOR ──
   The native cursor is only hidden once cursor.js has added .cur-on, so a script
   failure or a reduced-motion preference leaves a normal pointer behind. */
html.cur-on, html.cur-on body, html.cur-on a, html.cur-on .btn { cursor: none; }

#cur {
  position: fixed; width: 10px; height: 10px;
  background: var(--y); border-radius: 50%;
  pointer-events: none; z-index: 9999;
  transform: translate(-50%, -50%);
  mix-blend-mode: difference;
  transition: width .2s, height .2s;
}
#cur-ring {
  position: fixed; width: 36px; height: 36px;
  border: 1.5px solid rgba(255, 214, 0, 0.5); border-radius: 50%;
  pointer-events: none; z-index: 9998;
  transform: translate(-50%, -50%);
  transition: width .3s, height .3s;
}
#cur-burst {
  position: fixed; width: 36px; height: 36px;
  border: 1.5px solid rgba(255, 214, 0, 0.7); border-radius: 50%;
  pointer-events: none; z-index: 9997;
  transform: translate(-50%, -50%);
  opacity: 0;
}
#cur-burst.burst { animation: burst .4s ease-out forwards; }

@keyframes burst {
  0%   { width: 36px; height: 36px; opacity: .7; }
  100% { width: 72px; height: 72px; opacity: 0; }
}

body.pressing #cur { width: 6px; height: 6px; }
body.pressing #cur-ring { width: 28px; height: 28px; }

/* Grows over this design's own interactive things. shared.css targets .card,
   .chip and .od-card, none of which exist on these pages. */
body:has(a:hover) #cur,
body:has(.case:hover) #cur,
body:has(.m:hover) #cur,
body:has(.btn:hover) #cur { width: 18px; height: 18px; }

body:has(a:hover) #cur-ring,
body:has(.case:hover) #cur-ring,
body:has(.m:hover) #cur-ring,
body:has(.btn:hover) #cur-ring { width: 52px; height: 52px; border-color: rgba(255, 214, 0, 0.8); }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  padding: clamp(18px, 3.4vh, 56px) clamp(20px, 6vw, 64px) clamp(20px, 3.4vh, 40px);
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* Sized so the landing page fits the viewport without scrolling, and keeps
   fitting when the viewport is short: a bookmark row, a downloads bar or a
   1366x768 laptop all take height away. Every vertical measure below is in
   vh so the page compresses instead of spilling, and the type sizes are
   min(vw, vh) so they shrink on a short window as well as a narrow one.
   The width also keeps the arc on one row and the case descriptions on one
   line, which is where most of the saved height comes from. */
#page {
  max-width: 1040px;
  width: 100%;
  margin: 0 auto;
  flex: 1;
  /* Above the star canvas. */
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 3.4vh, 46px);
  /* On a tall screen the leftover height is shared out between all the sections
     rather than collecting in one place. Parking it with an auto margin left a
     visible void, first above the footer and then between the cases and Also.
     The gap above is the minimum, so on short screens this does nothing. */
  justify-content: space-between;
}

/* Space Grotesk, not mono: this doubles as the wordmark in the opening
   sequence, where it renders around 200px, and mono goes thin at that size. */
.identity {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--y);
}

/* The name is the title now, so it carries the weight the positioning line
   used to. Someone arriving after a warm intro is checking a name. */
.name {
  font-size: clamp(28px, min(5vw, 5.4vh), 52px);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.05;
  margin-top: clamp(8px, 1.4vh, 14px);
}

.tagline {
  font-size: clamp(15px, min(2vw, 2.3vh), 21px);
  color: var(--muted);
  line-height: 1.4;
  letter-spacing: -0.01em;
  text-wrap: balance;
  max-width: 56ch;
  margin-top: clamp(6px, 1.2vh, 12px);
}

.arc {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 26px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--dim);
  padding-top: clamp(12px, 2vh, 20px);
  border-top: 1px solid var(--border);
}
.arc b { color: var(--muted); font-weight: 400; }
.arc a { color: var(--dim); text-decoration: none; border-bottom: 1px solid var(--border); }
.arc a:hover, .arc a:focus-visible { color: var(--y); border-color: var(--y); }

/* A bordered card rather than another mono row: the .arc above is already a
   dim mono line, and a second one read as a repeat of it. The section name
   sits on the top border, knocked out with the page background behind it. */
.cases {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid rgba(255,214,0,0.38);
  padding: 6px clamp(16px, 2.4vw, 24px);
}
/* An h2 for the page outline, so the label is not weight-700 by default. */
.cases-l {
  position: absolute;
  top: 0;
  left: clamp(14px, 2vw, 20px);
  transform: translateY(-50%);
  background: var(--bg);
  padding: 0 9px;
  font-family: var(--mono);
  font-weight: 400;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--y);
}

.case {
  display: flex;
  flex-direction: column;
  gap: clamp(2px, 0.6vh, 5px);
  padding: clamp(12px, 2.2vh, 22px) 0;
  border-bottom: 1px solid var(--border);
  text-decoration: none;
  color: inherit;
  transition: padding-left 0.2s, border-color 0.2s;
}
/* The card supplies the outer edge, so the last divider would double it. */
.case:last-child { border-bottom: none; }
.case:hover, .case:focus-visible { padding-left: 10px; border-color: var(--y); outline: none; }
.case:hover .case-t, .case:focus-visible .case-t { color: var(--y); }
/* Name on the left, status on the right, so the status forms a column the
   eye can run down. Wraps on narrow screens rather than squashing. */
.case-h {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 4px 18px;
}
.case-t { font-size: clamp(16px, min(2.4vw, 2.5vh), 21px); font-weight: 700; letter-spacing: -0.02em; }
.case-d { font-size: clamp(13px, min(1.45vw, 1.65vh), 14.5px); color: var(--muted); max-width: 92ch; }
.case-m {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
}

/* The other surfaces, so the case card is visibly not everything there is.
   Deliberately quieter than that card: no yellow border, small type, four
   columns, so it reads as a directory rather than a second pitch. */
.more {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(9px, 1.5vh, 14px) 24px;
  padding-top: clamp(11px, 1.9vh, 18px);
  border-top: 1px solid var(--border);
}
.more-l {
  grid-column: 1 / -1;
  font-family: var(--mono);
  font-weight: 400;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
}

.m {
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-decoration: none;
  color: inherit;
  /* Padding rather than transform, so the hover shift cannot collide with the
     entrance animation's transform below. Same gesture as .case, smaller. */
  transition: padding-left 0.22s cubic-bezier(.23, 1, .32, 1);
}
.m:hover, .m:focus-visible { padding-left: 6px; }
.m:focus-visible { outline: none; }

/* align-self so the underline is the width of the words, not of the column. */
.m-t {
  position: relative;
  align-self: start;
  font-size: clamp(13.5px, min(1.5vw, 1.7vh), 15px);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.2;
}
.m-t::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -3px;
  width: 100%;
  height: 1px;
  background: var(--y);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.28s cubic-bezier(.23, 1, .32, 1);
}
.m:hover .m-t::after, .m:focus-visible .m-t::after { transform: scaleX(1); }

.m-d { font-size: clamp(11.5px, min(1.3vw, 1.45vh), 12.5px); color: var(--dim); line-height: 1.35; }

/* Marks the two that leave the site. Kept small enough to read as a hint, and
   it leans in the direction it is about to send you. */
.m-x {
  display: inline-block;
  font-size: 10.5px;
  color: var(--dim);
  transition: transform 0.25s cubic-bezier(.23, 1, .32, 1);
}
.m:hover .m-x, .m:focus-visible .m-x { transform: translate(2px, -2px); }
.m:hover .m-t, .m:focus-visible .m-t,
.m:hover .m-x, .m:focus-visible .m-x { color: var(--y); }

/* Entrance, staggered left to right, on the same easing the app pages use for
   their cards. Gated on .op-done so it is not spent behind the opening overlay
   on a first visit: opening.js sets that class whether it plays or skips. */
@keyframes m-in {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: none; }
}
.op-done .m { animation: m-in 0.55s cubic-bezier(.23, 1, .32, 1) both; }
.op-done .m:nth-child(3) { animation-delay: 0.07s; }
.op-done .m:nth-child(4) { animation-delay: 0.14s; }
.op-done .m:nth-child(5) { animation-delay: 0.21s; }

@media (prefers-reduced-motion: reduce) {
  .op-done .m { animation: none; }
  .m, .m-t::after, .m-x { transition: none; }
}

.foot {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  padding-top: clamp(14px, 2.6vh, 28px);
  border-top: 1px solid var(--border);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.foot a { color: var(--dim); text-decoration: none; }
.foot a:hover, .foot a:focus-visible { color: var(--y); }
/* Contact sits alone on the right, which is the whole emphasis it needs.
   Lowercase because an uppercased address stops looking like an address. */
.foot a.foot-c {
  margin-left: auto;
  text-transform: none;
  letter-spacing: 0.05em;
  color: var(--muted);
}
.foot a.foot-c:hover, .foot a.foot-c:focus-visible { color: var(--y); }

@media (max-width: 820px) {
  .more { grid-template-columns: repeat(2, 1fr); }
}

/* Short viewports. Measured: at 1366x610 the page overflowed by 2px and at
   1280x560 by 29px, which is a laptop with a bookmark row and a downloads bar.
   The vh scaling above is not steep enough there because the type floors stop
   shrinking, so the spacing takes the hit instead. Deliberately scoped to short
   windows: 1920x1080, 1440x900 and 820x1000 already fit and are left alone. */
@media (max-height: 720px) {
  body {
    padding-top: clamp(12px, 2.6vh, 56px);
    padding-bottom: clamp(12px, 2.6vh, 40px);
  }
  #page { gap: clamp(11px, 2.7vh, 46px); }
  .arc { padding-top: clamp(9px, 1.6vh, 20px); }
  .case { padding: clamp(9px, 1.8vh, 22px) 0; }
  .more { padding-top: clamp(9px, 1.5vh, 18px); }
  .foot { padding-top: clamp(11px, 2vh, 28px); }
}

@media (max-width: 560px) {
  .name { font-size: 32px; }
  .tagline { font-size: 16px; }
  .arc { gap: 6px 18px; }
  /* Once it wraps, the address next to LinkedIn reads as a second link in the
     same row, so it gets its own line instead. */
  .foot a.foot-c { margin-left: 0; flex-basis: 100%; }
}
