/*
 * The whole visual system for craftedby.si.
 *
 * The page is nothing but a grid of cards - no mark, no heading, no metadata -
 * so the cards carry the entire identity. They are treated as struck plates:
 * a cool pewter ground, a faintly lit face, a hairline edge that warms to brass
 * as you approach. Everything else stays out of the way.
 *
 * No build step and no framework. If this file ever needs a preprocessor,
 * something has gone wrong with the brief.
 */

/* ---------------------------------------------------------------- reset -- */

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

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

/* --------------------------------------------------------------- tokens -- */

:root {
  color-scheme: dark;

  /* Cool struck metal for the ground, warm metal reserved for the one moment
     of contact - the card edge under the cursor. */
  --pewter-900: #14181c;
  --pewter-800: #1b2126;
  --pewter-600: #2c353c;
  --steel-300: #9aa9b2;
  --chalk: #e8edf0;
  --brass: #c8973f;

  --rule: color-mix(in srgb, var(--pewter-600) 82%, transparent);

  --font-display: "Archivo", ui-sans-serif, system-ui, sans-serif;
  --font-body: "Instrument Sans", ui-sans-serif, system-ui, sans-serif;

  /* Wide enough for three cards with air between them. */
  --measure: 68rem;
  --gutter: clamp(1.5rem, 5vw, 3rem);

  --ease-strike: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ----------------------------------------------------------------- base -- */

body {
  min-height: 100svh;
  background-color: var(--pewter-900);
  color: var(--chalk);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* A faint hammered grain, so the ground reads as metal rather than flat dark. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.038;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* A cool wash from the top, as though the plates are lit from above. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(
    120% 60% at 50% -10%,
    rgba(154, 169, 178, 0.09),
    transparent 62%
  );
}

.shell {
  position: relative;
  z-index: 1;
  max-width: var(--measure);
  margin-inline: auto;
  padding: clamp(3rem, 10vw, 6rem) var(--gutter);
}

/* Present for screen readers, absent on screen. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ----------------------------------------------------------------- grid -- */

/* Three to a row, dropping to two and then one rather than letting the cards
   squeeze - the descriptions need a readable measure more than the row needs
   its count. */
.grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
}

@media (max-width: 64rem) {
  .grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 42rem) {
  .grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ----------------------------------------------------------------- card -- */

.card {
  display: flex;
  height: 100%;
  flex-direction: column;
  gap: 0.75rem;
  padding: clamp(1.5rem, 3vw, 1.875rem);
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: linear-gradient(168deg, var(--pewter-800), var(--pewter-900) 78%);
  box-shadow:
    inset 0 1px 0 rgba(232, 237, 240, 0.05),
    0 1px 2px rgba(0, 0, 0, 0.35);
  transition:
    border-color 220ms ease,
    transform 260ms var(--ease-strike),
    box-shadow 260ms ease;
}

.card:hover,
.card:focus-visible {
  border-color: color-mix(in srgb, var(--brass) 42%, var(--pewter-600));
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 rgba(232, 237, 240, 0.07),
    0 8px 22px rgba(0, 0, 0, 0.42);
}

.card__name {
  font-family: var(--font-display);
  font-variation-settings:
    "wdth" 108,
    "wght" 600;
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--chalk);
}

.card__body {
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--steel-300);
}

/* ---------------------------------------------------------------- focus -- */

:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 3px;
  border-radius: 2px;
}

/* --------------------------------------------------------------- motion -- */

@keyframes settle {
  from {
    opacity: 0;
    transform: translateY(0.75rem);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.grid > * {
  animation: settle 620ms var(--ease-strike) both;
}

/* Cards land left to right. Covers the first row of three; anything beyond
   inherits the last delay, which is close enough not to read as a gap. */
.grid > *:nth-child(2) {
  animation-delay: 80ms;
}

.grid > *:nth-child(n + 3) {
  animation-delay: 160ms;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}
