/* ===========================================================================
   JUST CREATE — motion, paper and the brush marks
   ---------------------------------------------------------------------------
   ⚠ EVERY RULE THAT HIDES ANYTHING IS SCOPED BEHIND `html.anim`, added by
     reveal.js and only when the visitor has not asked for reduced motion.
     Without the script the page is simply visible. A stylesheet that hides
     content and waits for JavaScript to bring it back is how a site ends up
     blank for the people least able to fix it — and on a page whose job is
     telling somebody when a class is, that is not a close call.
   ========================================================================= */

/* =========================================================================
   THE REVEAL
   Softer and slower than a shop's: this brand has no hard edges anywhere, so
   the motion should not either. Up 16px over two thirds of a second.
   ========================================================================= */
html.anim .reveal {
  opacity: 0;
  transform: translate3d(0, 16px, 0);
  transition:
    opacity .68s cubic-bezier(.22, .61, .36, 1) var(--reveal-delay, 0ms),
    transform .68s cubic-bezier(.22, .61, .36, 1) var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}
html.anim .reveal.is-in { opacity: 1; transform: none; will-change: auto; }

html.anim img.will-fade { opacity: 0; }
html.anim img.will-fade.is-loaded,
html.anim img.is-loaded { opacity: 1; transition: opacity .55s var(--ease); }

/* =========================================================================
   PAPER
   -------------------------------------------------------------------------
   ⚠ A WATERCOLOUR BRAND ON A PERFECTLY FLAT WHITE IS THE WRONG SURFACE. The
     logo is paint on paper; the page it sits on should have some tooth or
     the artwork reads as a sticker on a screen.

     Much lighter than a dark site's grain — 2%, multiplied rather than
     overlaid, so it darkens the highs a hair instead of adding light specks.
     Drawn as inline SVG turbulence: no request, no bytes, any screen size.
   ========================================================================= */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: .022;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='4'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23p)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  mix-blend-mode: multiply;
}
/* ⚠ z-index ONLY, AND ONLY FOR THE THINGS THAT ARE NOT POSITIONED ALREADY.
   This line used to read
       .site-header, .drawer, .modal, main, .site-footer
         { position: relative; z-index: 2; }
   and it silently broke three of the five. `.site-header` is `sticky`,
   `.drawer` and `.modal` are `fixed` — and this stylesheet loads AFTER
   styles.css, so `position: relative` won every time. The sticky header
   stopped sticking, and the mobile menu opened as a block 380px down the page
   with its last link off the bottom of it.

   It was invisible for a long time because the built `deploy/` folder that the
   tests grade did not yet contain motion.css, so the rule never applied to the
   thing being measured. The stylesheet 404'd and everything passed.

   Those three already sit at z-index 60, 90 and 100 — miles above the paper
   grain at 1 — so they need nothing from this file. `main` and `.site-footer`
   are statically positioned and are the only two that do. */
main, .site-footer { position: relative; z-index: 2; }

/* =========================================================================
   THE BRUSH UNDERLINE
   -------------------------------------------------------------------------
   Section headings are underlined with a stroke that has a painted edge
   rather than a 1px rule. It is the one piece of ornament on the site and it
   is the thing that ties the pages back to the logo — everything else here
   is clean type on paper, which on its own would belong to any business.

   Drawn as an inline SVG path so the ends taper and the edge wobbles the way
   a loaded brush does. A CSS border cannot do either.
   ========================================================================= */
.brush-rule {
  display: block;
  width: min(220px, 46%);
  height: 12px;
  margin-top: .55rem;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 220 12' preserveAspectRatio='none'%3E%3Cpath d='M2 7.4c26-3.2 52-4.6 78-4.1 24 .5 47 2.6 71 3.1 22 .4 44-.6 67-3.4-21 5.2-43 7.6-65 7.7-25 .1-49-2.1-74-2.6C55 8 34 8.6 2 7.4Z' fill='%235AA0C8'/%3E%3C/svg%3E");
  opacity: .85;
}
/* On a tinted band the sky blue disappears; the deeper ocean holds. */
.band--wash .brush-rule, .band--tint .brush-rule {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 220 12' preserveAspectRatio='none'%3E%3Cpath d='M2 7.4c26-3.2 52-4.6 78-4.1 24 .5 47 2.6 71 3.1 22 .4 44-.6 67-3.4-21 5.2-43 7.6-65 7.7-25 .1-49-2.1-74-2.6C55 8 34 8.6 2 7.4Z' fill='%231E648C'/%3E%3C/svg%3E");
}
/* It paints itself in, left to right, when its heading arrives.

   ⚠ ONLY INSIDE SOMETHING THAT ACTUALLY REVEALS. The first version clipped
   EVERY brush rule shut by default and opened it on `.reveal.is-in` — so any
   heading that is not inside a revealed element, which is most page titles,
   had its stroke clipped to nothing for ever. The ornament simply never
   appeared on half the site, and the failure looked exactly like "we forgot
   to add it there". Default open; clipped only where something will open
   it. */
html.anim .reveal .brush-rule {
  clip-path: inset(0 100% 0 0);
  transition: clip-path .75s cubic-bezier(.22, .61, .36, 1) .18s;
}
html.anim .reveal.is-in .brush-rule { clip-path: inset(0 0 0 0); }
@media (prefers-reduced-motion: reduce) {
  html.anim .reveal .brush-rule { clip-path: none; transition: none; }
}

/* =========================================================================
   THE WATERCOLOUR BLOOMS
   -------------------------------------------------------------------------
   Two soft washes behind the hero that drift very slowly against each other,
   so the ground looks like wet paint settling rather than a flat gradient.
   Slow enough (30s+) that it never reads as "something is moving" — it just
   stops the page feeling like a printout.
   ========================================================================= */
.bloom {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  filter: blur(46px);
  opacity: .5;
}
.bloom--sky  { background: var(--sky); }
.bloom--leaf { background: var(--leaf-light); }

html.anim .bloom--sky  { animation: bloom-a 34s ease-in-out infinite alternate; }
html.anim .bloom--leaf { animation: bloom-b 41s ease-in-out infinite alternate; }

@keyframes bloom-a {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(4%, -3%, 0) scale(1.13); }
}
@keyframes bloom-b {
  from { transform: translate3d(0, 0, 0) scale(1.06); }
  to   { transform: translate3d(-5%, 4%, 0) scale(.95); }
}
@media (prefers-reduced-motion: reduce) {
  html.anim .bloom { animation: none; }
}

/* =========================================================================
   HOVER AND PRESS
   ========================================================================= */
.class-card, .card-media {
  transition: box-shadow var(--quick), transform var(--quick),
              border-color var(--quick);
}
.card:hover .card-media { border-color: var(--ocean-mid); }

/* The name underlines from the left rather than everywhere at once. */
.card-name {
  background-image: linear-gradient(var(--ocean-mid), var(--ocean-mid));
  background-size: 0 2px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  transition: background-size var(--quick), color var(--quick);
}
.card:hover .card-name { background-size: 100% 2px; color: var(--ocean-deep); }

.btn { transition: background var(--quick), color var(--quick),
                   border-color var(--quick), box-shadow var(--quick),
                   transform .08s ease-out; }
.btn--primary:hover { transform: translateY(-1px); }
.btn--primary:active { transform: translateY(1px); }

@media (prefers-reduced-motion: reduce) {
  .class-card:hover, .btn--primary:hover { transform: none; }
}
