<3/products/personal-site/app/

globals.css

@import "tailwindcss";

/* ===========================================================================
   Site styles for the landing page and internal video tools.

   This is the single file to tweak for page-level look & feel. Reusable
   components own their own CSS:
     - Essay list item → components/EssayList.module.css
     - Video inspector → components/VideoInspector.module.css
   Those components still read the shared design tokens defined below.
=========================================================================== */

/* ---------------------------------------------------------------------------
   Design tokens (shared palette — components reference these too)
--------------------------------------------------------------------------- */
:root {
  --background: #fdfdfc; /* barely-warm white */
  --ink: #111;
  --ink-strong: #111;
  --caption: rgb(0 0 0 / 40%);
  --hairline: #f2f2f2;
  --viz-bg: #fbfbfa; /* visualization panel — near page-white, defined by its edge */
  --viz-edge: #eeeeea; /* hairline that separates a viz panel from the page */
  --code-bg: #f5f5f2;
  --accent: rgb(0 0 0 / 60%);
  /* Blue sampled from the user's ChatGPT link reference. */
  --link: #35579f;
  --link-hover: #24447f;
  --font-size: 0.875rem;
  --line-height: 1.25rem;
  --letter-spacing: -0.00563rem;
  /* Shared rhythm, taken from the approved essay layout. */
  --space-related: 1rem;
  --space-section: calc(2 * var(--space-related));
  --space-detail: calc(var(--space-related) / 2);
  --space-media-edge: calc((var(--line-height) - 1cap) / 2);
  /* benji.org: 582px outer column, 550px desktop content width. */
  --page-width: 36.375rem;
  --page-gutter: 1rem;
  --page-top: 5rem;
  --page-bottom: 2.5rem;
}

@theme inline {
  --color-background: var(--background);
  --color-ink: var(--ink);
  --color-ink-strong: var(--ink-strong);
  --color-caption: var(--caption);
  --color-hairline: var(--hairline);
  --font-sans: var(--font-sans);
}

/* ---------------------------------------------------------------------------
   Base typography — measured from benji.org, one size for everything
--------------------------------------------------------------------------- */
html {
  background: var(--background);
  font-family: var(--font-sans), ui-sans-serif, system-ui, sans-serif;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body {
  overflow-y: scroll;
  background: var(--background);
  color: var(--ink);
  font-size: var(--font-size);
  font-weight: 460;
  letter-spacing: var(--letter-spacing);
  line-height: var(--line-height);
}

/* Match the reference's reserved 6px scrollbar so the column stays centered. */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: transparent; border-radius: 100px; }
:hover::-webkit-scrollbar-thumb { background: rgb(0 0 0 / 15%); }
::-webkit-scrollbar-thumb:hover { background: rgb(0 0 0 / 25%); }

a {
  color: var(--link);
  text-decoration: none;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color 150ms ease;
}
a:visited { color: var(--link); }
a:hover, a:focus-visible {
  color: var(--link-hover);
  text-decoration: underline;
}
a:focus-visible, button:focus-visible {
  outline: 2px solid var(--link);
  outline-offset: 4px;
  border-radius: 2px;
}

small, code, pre, kbd, samp, sup, sub { font-size: inherit; }
button, input, select, textarea { font: inherit; }
strong, b { font-weight: 600; }

/* Nothing is bigger than anything else: headings inherit the base size.
   Hierarchy comes only from weight and color. */
h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: inherit;
  font-weight: 500;
  line-height: inherit;
}

::selection {
  color: var(--ink);
  background: #ededed;
}

/* ---------------------------------------------------------------------------
   Page shell — centered landing-page column
--------------------------------------------------------------------------- */
.page {
  margin: 0 auto;
  width: 100%;
  max-width: var(--page-width);
  padding: var(--page-top) var(--page-gutter) var(--page-bottom);
}

@media (max-width: 768px) {
  :root {
    --page-gutter: 1.5rem;
    --page-top: 2rem;
  }
}

/* ---------------------------------------------------------------------------
   "Cards being laid down" — subtle staggered entrance for page content.
   Applied to a container; its direct children animate in one after another.
--------------------------------------------------------------------------- */
@keyframes card-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.reveal > * {
  opacity: 0;
  animation: card-in 0.62s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.reveal > *:nth-child(1) {
  animation-delay: 0.02s;
}
.reveal > *:nth-child(2) {
  animation-delay: 0.09s;
}
.reveal > *:nth-child(3) {
  animation-delay: 0.16s;
}
.reveal > *:nth-child(4) {
  animation-delay: 0.23s;
}
.reveal > *:nth-child(5) {
  animation-delay: 0.3s;
}
.reveal > *:nth-child(6) {
  animation-delay: 0.37s;
}
.reveal > *:nth-child(7) {
  animation-delay: 0.44s;
}
.reveal > *:nth-child(8) {
  animation-delay: 0.51s;
}
.reveal > *:nth-child(9) {
  animation-delay: 0.58s;
}
.reveal > *:nth-child(10) {
  animation-delay: 0.65s;
}
.reveal > *:nth-child(n + 11) {
  animation-delay: 0.72s;
}

@media (prefers-reduced-motion: reduce) {
  .reveal > * {
    opacity: 1;
    animation: none;
  }
}

/* ---------------------------------------------------------------------------
   Landing page
--------------------------------------------------------------------------- */
.landing {
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}

.landing__photo {
  width: 100%;
  max-width: 100px;
  aspect-ratio: 1 / 1; /* the box is always square... */
}

.landing__photo-inner {
  position: relative;
  width: 100%;
  height: 100%; /* ...so the inner fills a square, and 50% is a true circle */
  overflow: hidden;
  border-radius: 50%;
}

.landing__photo-inner img {
  object-fit: cover;
}

.landing__name-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.landing__name {
  font-weight: 480;
  color: var(--ink-strong);
}

.landing__divider {
  width: 1px;
  height: 1em;
  background: var(--hairline);
}

.landing__x {
  display: inline-flex;
  align-items: center;
  color: var(--caption);
  transition: color 0.2s ease;
}

.landing__x:hover {
  color: var(--ink-strong);
}

.landing__contact {
  color: var(--link);
  text-decoration: none;
}

.landing__contact:hover, .landing__contact:focus-visible {
  color: var(--link-hover);
  text-decoration: underline;
}

/* ---------------------------------------------------------------------------
   Essay page
--------------------------------------------------------------------------- */
.essay-title {
  font-weight: 500;
  color: var(--ink-strong);
}

.essay-date {
  margin-top: 0.25rem;
  color: var(--caption);
}

.essay-article {
  margin-top: 1.5rem;
}

.essay-body {
  color: var(--ink);
}

.essay-body > * + * {
  margin-top: 1rem;
}

.essay-body h1,
.essay-body h2,
.essay-body h3,
.essay-body h4 {
  margin-top: 2.25rem;
  color: var(--ink-strong);
  font-weight: 560;
}

.essay-body strong {
  color: var(--ink-strong);
  font-weight: 600;
}

.essay-body a {
  color: var(--link);
  text-decoration: none;
}

.essay-body a:hover, .essay-body a:focus-visible {
  color: var(--link-hover);
  text-decoration: underline;
}

.essay-body ul,
.essay-body ol {
  padding-left: 1.25em;
}

.essay-body ul {
  list-style: disc;
}

.essay-body ol {
  list-style: decimal;
}

.essay-body li + li {
  margin-top: 0.4em;
}

.essay-body blockquote {
  padding-left: 1em;
  border-left: 2px solid var(--hairline);
  color: var(--accent);
}

.essay-body code {
  padding: 0.1em 0.35em;
  border-radius: 5px;
  background: var(--code-bg);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: inherit;
}

.essay-body hr {
  margin: 3.5rem 0;
  border: 0;
  border-top: 1px solid var(--hairline);
}