/* ==========================================================================
   cleeklab — reusable components
   Each block is self-contained: copy its HTML + this CSS to reuse it.

   1.  Icon            7.  Label
   2.  Logo            8.  Eyebrow
   3.  Copper period   9.  Tag
   4.  Text sweep      10. Project preview
   5.  Button          11. Site header + nav
   6.  Text link       12. Site footer
                       13. Toast
   ========================================================================== */

/* Shared animation: one soft bounce. Set --float-distance on the element. */
@keyframes float {
  0%, 100% { transform: translateY(0); }
  35%      { transform: translateY(calc(var(--float-distance) * -1)); }
  65%      { transform: translateY(calc(var(--float-distance) * .15)); }
}
@keyframes rise-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
/* Added by JS for the "." easter egg */
.is-hopping { animation: float var(--dur-float) var(--ease-float) both; }


/* 1. Icon — inline SVG line icons that inherit text colour
   <svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><path d="…"/></svg> */
.icon {
  flex: none;
  width: 1.15em;
  height: 1.15em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}


/* 2. Logo — the supplied artwork shown twice: the body with the dot cut out,
   and the dot alone on top so it can float. Nothing is redrawn.
   Set the size with --logo-height. */
.logo {
  position: relative;
  display: inline-block;
  line-height: 0;
  --float-distance: 5px;
}
.logo img {
  height: var(--logo-height, 32px);
  width: auto;
  max-width: none;
}
.logo__dot {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}
/* Dot position in each artwork, as % of the image */
.logo--horizontal .logo__body { clip-path: polygon(0 0, 6.8% 0, 6.8% 28%, 14.4% 28%, 14.4% 0, 100% 0, 100% 100%, 0 100%); }
.logo--horizontal .logo__dot  { clip-path: inset(0 85.6% 72% 6.8%); }
.logo--stacked { --float-distance: 8px; }
.logo--stacked .logo__body { clip-path: polygon(0 0, 40% 0, 40% 19.5%, 60% 19.5%, 60% 0, 100% 0, 100% 100%, 0 100%); }
.logo--stacked .logo__dot  { clip-path: inset(0 40% 80.5% 40%); }

.logo:hover .logo__dot,
a:hover .logo__dot {
  animation: float var(--dur-float) var(--ease-float);
}


/* 3. Copper period — end a heading with <span class="period">.</span>
   Hovering the heading makes it bounce once. */
.period {
  display: inline-block;
  color: var(--copper-500);
  --float-distance: .14em;
}
:is(h1, h2, h3):hover .period {
  animation: float var(--dur-float) var(--ease-float);
}


/* 4. Text sweep — text colour closes in from both edges on hover.
   Put .sweep on the text itself (inside the link). */
.sweep {
  --sweep-from: var(--navy-900);
  --sweep-to: var(--copper-600);
  color: var(--sweep-from);
  background:
    linear-gradient(var(--sweep-to), var(--sweep-to)) left  / 0 100% no-repeat,
    linear-gradient(var(--sweep-to), var(--sweep-to)) right / 0 100% no-repeat,
    linear-gradient(var(--sweep-from), var(--sweep-from));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  transition: background-size var(--dur-hover) var(--ease-out);
}
a:hover .sweep,
a:focus-visible .sweep {
  background-size: 50.5% 100%, 50.5% 100%, 100% 100%;
}


/* 5. Button — fill spreads from where the pointer enters (JS sets --pointer-x/y).
   <a class="button button--primary" href="…"><span>Label</span> <svg class="icon button__arrow">…</svg></a> */
.button {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 44px;
  padding: 0 20px;
  border: 1px solid transparent;
  border-radius: var(--radius-1);
  font: 600 15px/1 var(--font-sans);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--dur-hover) var(--ease-out), transform var(--dur-instant) var(--ease-out);
}
.button::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: var(--pointer-x, 50%);
  top: var(--pointer-y, 50%);
  width: var(--fill-size, 300px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--button-fill);
  transform: translate(-50%, -50%) scale(0);
  transition: transform var(--dur-fill) var(--ease-float);
  pointer-events: none;
}
.button:hover::before { transform: translate(-50%, -50%) scale(1); }
.button:active { transform: translateY(1px); }

.button--primary { --button-fill: var(--action-hover); background: var(--action); color: var(--white); }
.button--primary:hover { color: var(--white); }
.button--primary:active::before { background: var(--action-press); }

.button--secondary { --button-fill: var(--navy-900); background: transparent; color: var(--navy-900); border-color: var(--navy-900); }
.button--secondary:hover { color: var(--white); }

.button--large { height: 56px; padding: 0 28px; font-size: 17px; }

.button__arrow { transition: transform var(--dur-arrow) var(--ease-float); }
.button:hover .button__arrow,
.text-link:hover .button__arrow { transform: translateX(8px); }


/* 6. Text link — copper hairline; on hover a navy underline closes in from both ends */
.text-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding-bottom: 3px;
  font: 600 15px/1.3 var(--font-sans);
  color: var(--navy-900);
  text-decoration: none;
  background:
    linear-gradient(var(--navy-900), var(--navy-900)) left  bottom / 0 2px no-repeat,
    linear-gradient(var(--navy-900), var(--navy-900)) right bottom / 0 2px no-repeat,
    linear-gradient(var(--copper-500), var(--copper-500)) left bottom / 100% 1px no-repeat;
  transition: background-size var(--dur-hover) var(--ease-out);
}
.text-link:hover {
  color: var(--navy-900);
  background-size: 50.5% 2px, 50.5% 2px, 100% 1px;
}


/* 7. Label — small mono uppercase text for meta information */
.label {
  font: var(--type-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
}
.label--accent { color: var(--text-accent); }


/* 8. Eyebrow — numbered section label above a heading */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font: var(--type-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-accent);
}
.eyebrow__num { color: var(--text-muted); }


/* 9. Tag — lowercase category pill; soft gray on hover or when its project is hovered */
.tag {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 9px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-pill);
  color: var(--gray-700);
  font: 500 12px/1 var(--font-mono);
  white-space: nowrap;
  transition: background-color var(--dur-hover) var(--ease-out), border-color var(--dur-hover) var(--ease-out);
}
.tag:hover,
.project:hover .tag,
.project:focus-visible .tag {
  background: var(--gray-100);
  border-color: var(--gray-300);
}


/* 10. Project preview — one entry in the directory. Three layouts:
   .project--feature (large, image left), .project--card (image on top), .project--row (text only) */
.project {
  position: relative;
  display: grid;
  color: inherit;
  text-decoration: none;
}
.project:hover { color: inherit; }
.project__media {
  aspect-ratio: 4 / 3;
  background: var(--navy-50);
  overflow: hidden;
}
.project__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-arrow) var(--ease-out);
}
.project:hover .project__media img { transform: scale(1.025); }

.project__code { font: 500 12px/1 var(--font-mono); letter-spacing: .04em; color: var(--text-muted); }
.project__title {
  font: 700 var(--text-xl)/1.1 var(--font-display);
  letter-spacing: var(--tracking-heading);
}
/* Copper underline drawn left → right on hover */
.project__title span {
  background: linear-gradient(var(--copper-500), var(--copper-500)) 0 100% / 0 2px no-repeat;
  transition: background-size var(--dur-hover) var(--ease-out);
}
.project:hover .project__title span,
.project:focus-visible .project__title span { background-size: 100% 2px; }
.project__summary { max-width: 56ch; font: 400 16px/1.5 var(--font-sans); color: var(--text-secondary); }
.project__tags { display: flex; flex-wrap: wrap; gap: 6px; }

.project--feature {
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  align-items: end;
  gap: var(--space-7);
}
.project--feature .project__media { aspect-ratio: 16 / 11; }
.project--feature .project__title { font-size: var(--text-3xl); line-height: 1.05; }
.project--feature .project__body { display: grid; gap: var(--space-4); padding-bottom: var(--space-2); }

.project--card { gap: var(--space-4); }
.project--card .project__code { margin-top: var(--space-2); }
.project--card .project__body { display: grid; gap: var(--space-3); }

.project--row {
  grid-template-columns: 96px minmax(0, 1.3fr) minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--space-5);
  padding: var(--space-6) 0;
  border-top: 1px solid var(--border-subtle);
}
.project--row .project__title { font-size: var(--text-2xl); }
.project--row .project__body { display: grid; gap: var(--space-3); }
.project__go {
  align-self: center;
  width: 24px;
  height: 24px;
  color: var(--navy-900);
  opacity: .3;
  transition: opacity var(--dur-hover) var(--ease-out), transform var(--dur-hover) var(--ease-out), color var(--dur-hover) var(--ease-out);
}
.project--row:hover .project__go { opacity: 1; transform: translateX(4px); color: var(--copper-600); }

@media (max-width: 760px) {
  .project--feature { grid-template-columns: 1fr; gap: var(--space-5); }
  .project--row { grid-template-columns: 1fr; gap: var(--space-3); }
  .project__go { display: none; }
}


/* 11. Site header + nav
   One nav list. Desktop: inline links with a sliding copper dot.
   Mobile (≤760px): hidden behind the menu button, opens as a full-width panel. */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: rgba(255, 255, 255, .92);
  -webkit-backdrop-filter: saturate(1.4) blur(12px);
  backdrop-filter: saturate(1.4) blur(12px);
  border-bottom: 1px solid var(--border-subtle);
}
.site-header__inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  height: var(--header-height);
}
.site-header__brand { display: inline-flex; --logo-height: 26px; }

.site-nav { position: relative; }
.site-nav__list {
  display: flex;
  gap: var(--space-6);
  margin: 0;
  padding: 0;
  list-style: none;
}
.nav-link {
  display: inline-flex;
  align-items: center;
  height: 40px;
  font: 500 15px/1 var(--font-sans);
  text-decoration: none;
}

/* The single copper dot that follows hover/focus and rests under the current section (JS positions it) */
.nav-dot {
  position: absolute;
  top: 0;
  left: 0;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--copper-500);
  opacity: 0;
  pointer-events: none;
}
.nav-dot.is-ready {
  transition: transform 480ms var(--ease-spring), opacity var(--dur-hover) var(--ease-out);
}

.menu-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-1);
  background: transparent;
  color: var(--navy-900);
  font-size: 20px;
  cursor: pointer;
  transition: background-color var(--dur-hover) var(--ease-out);
}
.menu-toggle:hover { background: var(--navy-50); }
.menu-toggle .icon--close { display: none; }
.menu-toggle[aria-expanded="true"] .icon--open { display: none; }
.menu-toggle[aria-expanded="true"] .icon--close { display: block; }

@media (max-width: 760px) {
  .menu-toggle { display: inline-flex; }
  .nav-dot { display: none; }
  .site-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    padding: var(--space-3) var(--gutter) var(--space-6);
    background: var(--white);
    border-bottom: 1px solid var(--border-subtle);
    box-shadow: var(--shadow-pop);
  }
  .site-nav[data-open="true"] { display: block; animation: rise-in var(--dur-hover) var(--ease-out); }
  .site-nav__list { display: grid; gap: 0; }
  .nav-link {
    position: relative;
    width: 100%;
    height: 56px;
    font: 600 24px/1 var(--font-display);
    letter-spacing: var(--tracking-heading);
    border-bottom: 1px solid var(--border-subtle);
  }
  .nav-link[aria-current]::after {
    content: "";
    position: absolute;
    right: 4px;
    top: 50%;
    width: 6px;
    height: 6px;
    margin-top: -3px;
    border-radius: 50%;
    background: var(--copper-500);
  }
}


/* 12. Site footer — navy band with the all-white logo */
.site-footer { background: var(--navy-900); color: var(--navy-200); }
.site-footer .sweep { --sweep-from: var(--navy-200); --sweep-to: var(--white); }
.site-footer__inner {
  display: grid;
  gap: var(--space-8);
  padding-top: var(--space-9);
  padding-bottom: var(--space-6);
}
.site-footer__top {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-7);
}
.site-footer__brand { --logo-height: 30px; }
.site-footer__tagline {
  margin-top: var(--space-5);
  max-width: 34ch;
  font: 400 19px/1.45 var(--font-serif);
}
.site-footer__heading {
  margin: 0 0 var(--space-4);
  font: var(--type-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--navy-300);
}
.site-footer__list { display: grid; gap: 12px; margin: 0; padding: 0; list-style: none; }
.site-footer__list a { font: 500 15px/1.3 var(--font-sans); text-decoration: none; }
.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-4);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border-inverse);
  font: 400 12px/1.4 var(--font-mono);
  color: var(--navy-300);
}
@media (max-width: 760px) {
  .site-footer__top { grid-template-columns: 1fr 1fr; }
  .site-footer__top > :first-child { grid-column: 1 / -1; }
}


/* 13. Toast — short message in the bottom-right corner (JS: showToast(title, message)) */
.toast-region {
  position: fixed;
  right: var(--space-5);
  bottom: var(--space-5);
  z-index: var(--z-toast);
}
.toast {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  width: min(400px, calc(100vw - 32px));
  padding: 16px 12px 16px 18px;
  background: var(--navy-900);
  color: var(--white);
  border-radius: var(--radius-1);
  box-shadow: var(--shadow-pop);
  animation: rise-in var(--dur-arrow) var(--ease-out);
}
.toast__dot { flex: none; width: 10px; height: 10px; margin-top: 5px; border-radius: 50%; background: var(--copper-400); }
.toast__body { flex: 1; min-width: 0; display: grid; gap: 4px; }
.toast__title { font: 600 15px/1.3 var(--font-sans); }
.toast__message { font: 400 14px/1.45 var(--font-sans); color: var(--navy-200); }
.toast__close {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: var(--radius-1);
  background: transparent;
  color: var(--white);
  cursor: pointer;
  transition: background-color var(--dur-hover) var(--ease-out);
}
.toast__close:hover { background: rgba(255, 255, 255, .1); }
@media (max-width: 480px) {
  .toast-region { left: var(--space-4); right: var(--space-4); bottom: var(--space-4); }
  .toast { width: 100%; }
}
