/* 
  animations.css 
  Reskinned styles for all portfolio animations.
  All colors map to global CSS variables from style.css.
*/

/* --- Shared Animation Defaults --- */
.anim-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
  box-sizing: border-box;
  font-family: var(--font-body);
  color: var(--text-body);
}

.anim-header {
  text-align: center;
  max-width: 580px;
  margin-bottom: 24px;
}

.anim-eyebrow {
  font-size: 13px;
  font-weight: var(--w-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 12px;
}

.anim-title {
  font-family: var(--font-display);
  font-weight: var(--w-semibold);
  font-size: clamp(26px, 3vw, 38px);
  line-height: 1.2;
  color: var(--text-strong);
}

/* --- 1. LLM Rollout --- */
.llm-sentence {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 10px 14px;
  max-width: 820px;
  font-size: clamp(26px, 3vw, 36px);
  line-height: 1.3;
  min-height: 46px;
}
.llm-word {
  font-family: var(--font-display);
  color: var(--text-strong);
  white-space: nowrap;
}
.llm-word.tok { opacity: 0; transition: opacity .4s; }
.llm-word.settled { color: var(--accent); }

.llm-slot {
  position: absolute;
  left: 0; top: 0;
  display: inline-flex;
  flex-direction: column;
  height: 1.3em;
  width: 6.5ch;
  overflow: hidden;
  border-bottom: 1.5px solid var(--accent);
  pointer-events: none;
}
.llm-slot-track { display: flex; flex-direction: column; will-change: transform; }
.llm-slot-item {
  height: 1.3em;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  color: var(--text-strong);
  white-space: nowrap;
}

.llm-panel {
  width: min(500px, 90vw);
  max-width: 100%;
  min-height: 188px;
  display: flex;
  flex-direction: column;
  gap: 11px;
  justify-content: center;
}
.llm-cand {
  display: flex;
  align-items: center;
  gap: 14px;
  opacity: .85;
  transition: opacity .3s;
}
.llm-cand-word {
  font-family: var(--font-mono);
  font-size: 13px;
  width: 110px;
  text-align: right;
  color: var(--text-muted);
  transition: color .3s;
}
.llm-cand-barwrap {
  flex: 1;
  height: 7px;
  background: var(--line-soft);
  border-radius: 3px;
  overflow: hidden;
}
.llm-cand-bar {
  height: 100%;
  width: 0;
  background: var(--accent);
  border-radius: 3px;
  transition: width .5s cubic-bezier(.4,0,.2,1);
}
.llm-cand-prob {
  font-family: var(--font-mono);
  font-size: 13px;
  width: 42px;
  text-align: right;
  color: var(--text-muted);
  transition: color .3s;
}
.llm-cand.win { opacity: 1; }
.llm-cand.win .llm-cand-word,
.llm-cand.win .llm-cand-prob {
  color: var(--accent);
}
.llm-cand.win .llm-cand-bar {
  background-color: var(--accent);
}

/* --- 2. MILP Simplex --- */
.milp-wrap {
  display: flex;
  gap: clamp(32px, 6vw, 72px);
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  width: min(1000px, 100%);
}
.milp-sidebar { flex: 1 1 220px; max-width: 280px; }
.milp-tagline {
  font-family: var(--font-body);
  font-size: clamp(18px, 2.2vw, 24px);
  font-weight: var(--w-regular);
  line-height: var(--lh-relaxed);
  color: var(--text-body);
  margin-bottom: 32px;
}
/* The problem, written out as the actual MILP. The Gomory cut is added by
   writing a new constraint line into it mid-animation. Monospace + white-space
   pre so the coefficient columns line up like a textbook formulation. */
.milp-model {
  display: flex;
  flex-direction: column;
  font-family: var(--font-mono);
  font-size: 17px;
  line-height: 1.45;
  letter-spacing: .01em;
  margin-bottom: 28px;
}
.milp-row {
  display: flex;
  gap: 12px;
  margin-bottom: 7px;
  color: var(--text-body);
}
.milp-row:last-child { margin-bottom: 0; }
.milp-row-key {
  flex: 0 0 10.5ch;
  text-align: right;
  color: var(--text-muted);
  white-space: pre;
}
.milp-row-body { white-space: pre; }

/* Collapsed until the cut fires, then grows in — a line added to the model.
   Margin animates alongside max-height so it reserves no space while hidden. */
.milp-row--cut {
  max-height: 0;
  margin-bottom: 0;
  overflow: hidden;
  opacity: 0;
  transform: translateX(-6px);
  transition: max-height .5s ease, margin-bottom .5s ease, opacity .45s ease .05s, transform .5s ease;
}
.milp-row--cut .milp-row-key { color: var(--mocha-700); }
.milp-row--cut .milp-row-body { color: var(--mocha-700); font-weight: 600; }
.milp-row--cut.visible {
  max-height: 2em;
  margin-bottom: 7px;
  opacity: 1;
  transform: none;
}

/* Live readout — the current vertex and objective as the simplex walks. */
.milp-data {
  display: flex;
  gap: clamp(24px, 4vw, 40px);
  margin-bottom: 24px;
}
.milp-pair { display: flex; flex-direction: column; gap: 4px; }
.milp-pair-label {
  font-size: 13px;
  font-weight: var(--w-medium);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.milp-pair-value {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 26px;
  line-height: 1.1;
  color: var(--text-strong);
  transition: color .4s;
  font-variant-numeric: tabular-nums;
}
.milp-pair-value.accent { color: var(--accent); }

.milp-phase-line {
  font-family: var(--font-body);
  font-size: var(--text-md);
  font-weight: var(--w-regular);
  line-height: var(--lh-relaxed);
  color: var(--text-body);
  transition: color .5s, opacity .5s;
}
.milp-phase-line.active-lp { color: var(--accent); }
.milp-phase-line.active-cut { color: var(--mocha-700); }
.milp-phase-line.active-ip { color: var(--accent); }

.milp-chart { flex: 0 0 auto; width: clamp(300px, 52vw, 540px); }
/* Clip to the chart box: the constraint lines are drawn overshooting the plot
   on purpose (so they span the feasible region), and overflow would let them
   bleed across the card. */
.milp-board { display: block; width: 100%; height: auto; overflow: hidden; }

/* --- 3. Monty Hall --- */
#mh-intro-line {
  font-family: var(--font-body);
  font-size: clamp(18px, 2.2vw, 24px);
  font-weight: var(--w-regular);
  line-height: var(--lh-relaxed);
  color: var(--text-body);
  text-align: center;
  transition: opacity .35s;
  max-width: 560px;
}
#mh-intro-line.accent { color: var(--accent); }
.mh-stage {
  position: relative;
  width: min(560px, 94vw);
  height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.mh-scene {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 26px;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .5s ease, transform .5s ease;
  pointer-events: none;
}
.mh-scene.in { opacity: 1; transform: none; }

.mh-doors {
  position: relative;
  display: flex;
  gap: clamp(18px, 4vw, 38px);
  padding: 14px;
}
.mh-ghi {
  position: absolute;
  border-radius: 14px;
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent);
  opacity: 0;
  /* Behind the doors (z-index 1) so the filled highlight reads as a halo
     around doors 2 & 3 instead of painting over and hiding them. */
  z-index: 0;
  pointer-events: none;
  transition: opacity .5s, left .65s cubic-bezier(.5,0,.2,1), width .65s cubic-bezier(.5,0,.2,1), top .65s, height .65s;
}
.mh-door {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.mh-door-frame {
  width: clamp(58px, 9vw, 76px);
  height: clamp(92px, 15vw, 120px);
  border-radius: 9px;
  position: relative;
  overflow: hidden;
  border: 1.5px solid var(--line-base);
  transition: border-color .5s, box-shadow .5s, transform .3s;
}
.mh-door.stay .mh-door-frame {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-ring);
}
.mh-door.switch .mh-door-frame {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-ring);
}
.mh-door-content {
  position: absolute;
  inset: 0;
  background: var(--surface-sunken);
  display: flex;
  align-items: center;
  justify-content: center;
}
.mh-door-face {
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, var(--espresso-800), var(--espresso-900));
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity .55s ease;
}
.mh-door-face::after {
  content: "";
  position: absolute;
  right: 9px;
  top: 50%;
  width: 5px;
  height: 20px;
  border-radius: 3px;
  background: var(--line-base);
  transform: translateY(-50%);
}
.mh-door.open .mh-door-face { opacity: 0; }
.mh-door-num {
  font-family: var(--font-display);
  font-size: clamp(24px, 3.5vw, 32px);
  color: var(--accent);
  opacity: .85;
}
.mh-door-label {
  font-size: 13px;
  font-weight: var(--w-medium);
  letter-spacing: .07em;
  color: var(--text-muted);
  text-transform: uppercase;
  transition: color .4s;
}
.mh-door.stay .mh-door-label,
.mh-door.switch .mh-door-label {
  color: var(--accent);
}
.mh-door-prob {
  position: absolute;
  bottom: -26px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-display);
  font-style: italic;
  font-size: 24px;
  color: var(--text-muted);
  opacity: 0;
  transition: opacity .4s, color .4s;
  white-space: nowrap;
}
.mh-door-prob.show { opacity: 1; }
.mh-door.stay .mh-door-prob,
.mh-door.switch .mh-door-prob {
  color: var(--accent);
}
.mh-car { color: var(--accent); }
.mh-goat { color: var(--text-muted); }
/* Size the car/goat behind each door relative to the frame so they read large
   and stay proportional as the door clamps down on smaller screens. */
.mh-door-content svg { width: 72%; height: auto; }

.mh-scen-cap {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 19px;
  color: var(--text-muted);
}
.mh-scen-head {
  display: grid;
  grid-template-columns: repeat(3, 36px) 60px;
  gap: 10px;
  justify-content: center;
}
.mh-scen-head span {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-muted);
  text-align: center;
}
/* The pair enumeration shows only the two unpicked doors + an outcome tag, so it
   needs its own grid — the default scen-head/srow grids are sized for three
   cells, which squeezed "Door 2 / Door 3" into a wrapping 36px column and let
   the icons crowd the win/lose tag. Two roomy cells, a clear gap, then the tag. */
.mh-scen-head.pair-head,
.mh-srow.pair-row {
  grid-template-columns: repeat(2, 46px) 72px;
  gap: 20px;
}
.mh-scen-head.pair-head span {
  font-size: 14px;
  white-space: nowrap;
}
.mh-srow {
  display: grid;
  grid-template-columns: repeat(3, 36px) 60px;
  gap: 10px;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: translateX(8px);
  transition: opacity .45s, transform .45s;
}
.mh-srow.in { opacity: 1; transform: none; }
.mh-cell {
  width: 46px;
  height: 46px;
  border-radius: 6px;
  background: var(--surface-sunken);
  border: 1px solid var(--line-base);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
.mh-cell.pick {
  border-color: var(--accent);
  box-shadow: 0 0 0 1.5px var(--accent-ring);
}
.mh-cell svg { width: 34px; height: auto; }
.mh-cell.removed { opacity: .3; }
.mh-cell.removed::after {
  content: "\2715";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  color: var(--text-strong);
  font-weight: var(--w-regular);
}
.mh-cell.keep {
  border-color: var(--accent);
  box-shadow: 0 0 0 1.5px var(--accent-ring);
}
.mh-outcome {
  opacity: 0;
  transition: opacity .35s;
  font-size: 12px;
  font-weight: var(--w-semibold);
  letter-spacing: .06em;
  text-transform: uppercase;
  text-align: center;
  padding: 4px 0;
  border-radius: 4px;
}
.mh-outcome.show { opacity: 1; }
.mh-outcome.win {
  color: var(--accent);
  background: var(--accent-soft);
}
.mh-outcome.lose {
  color: var(--text-muted);
  background: var(--line-soft);
}

.mh-final-big {
  font-family: var(--font-display);
  font-weight: var(--w-semibold);
  font-size: clamp(42px, 3.5vw, 56px);
  color: var(--accent);
  text-align: center;
}
.mh-final-sub {
  font-family: var(--font-body);
  font-size: var(--text-md);
  font-weight: var(--w-regular);
  line-height: var(--lh-relaxed);
  color: var(--text-body);
  margin-top: 10px;
  text-align: center;
}

.mh-caption {
  height: 110px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  width: min(640px, 94vw);
}
.mh-caption-line {
  font-family: var(--font-body);
  font-size: clamp(18px, 2.2vw, 24px);
  font-weight: var(--w-regular);
  line-height: var(--lh-relaxed);
  color: var(--text-body);
  transition: opacity .35s;
}
.mh-caption-line.accent { color: var(--accent); }

/* --- 4. Pareto Efficiency --- */
.pareto-counters {
  display: flex;
  gap: clamp(32px, 8vw, 96px);
  align-items: flex-end;
  margin-bottom: 24px;
}
.pareto-counter {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.pareto-counter-label {
  font-size: 13px;
  font-weight: var(--w-regular);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.pareto-counter-value {
  font-family: var(--font-display);
  font-weight: var(--w-semibold);
  font-size: clamp(42px, 5.5vw, 64px);
  line-height: 1;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.pareto-cost-val { color: var(--accent); }
.pareto-quality-val { color: var(--mocha-700); }

.pareto-chart { width: min(520px, 90vw); max-width: 100%; }
.pareto-board { display: block; width: 100%; height: auto; overflow: visible; }

/* --- Mobile intro keyframes --- */
@keyframes mobile-fade-out {
  to { opacity: 0; pointer-events: none; }
}
@keyframes mobile-fade-in {
  to { opacity: 1; }
}

/* MILP mobile intro element: hidden by default (desktop) */
.milp-mobile-intro { display: none; }

/* ==========================================================================
   MOBILE — max-width: 559px
   The 560px escape hatch in style.css enables scrolling. All overrides here
   are additive — desktop rules are completely untouched.
   ========================================================================== */
@media (max-width: 559px) {

  /* Shared */
  .anim-container {
    padding: 12px;
    position: relative;
  }

  /* LLM Rollout: scale down sentence font */
  .llm-sentence {
    font-size: clamp(18px, 3vw, 36px);
    gap: 6px 10px;
  }

  /* MILP Simplex: text-first intro overlay, then stacked chart + compact sidebar */
  .milp-mobile-intro {
    display: flex;
    position: absolute;
    inset: 0;
    z-index: 10;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 24px;
    font-family: var(--font-display);
    font-size: clamp(22px, 5.5vw, 34px);
    font-weight: 700;
    color: var(--text-strong);
    line-height: 1.25;
    animation: mobile-fade-out 0.5s 2.8s ease-in forwards;
  }

  .milp-tagline { display: none; }

  .milp-wrap {
    flex-direction: column;
    gap: 16px;
    width: 100%;
    opacity: 0;
    animation: mobile-fade-in 0.5s 3.0s ease-out forwards;
  }

  /* Chart on top, full width */
  .milp-chart {
    width: clamp(240px, 90vw, 540px);
    flex: none;
    order: -1;
  }

  /* Sidebar compact below chart */
  .milp-sidebar {
    flex: none;
    max-width: 100%;
    width: 100%;
  }

  .milp-model {
    font-size: 13px;
    margin-bottom: 16px;
  }

  .milp-pair-value { font-size: 18px; }
  .milp-data { margin-bottom: 12px; }
  .milp-phase-line { font-size: var(--text-base); }

  /* Monty Hall: reduce fixed heights, ensure text wraps */
  .mh-stage { height: 240px; }

  .mh-caption {
    height: auto;
    min-height: 80px;
  }

  .mh-final-big { font-size: 32px; }

  #mh-intro-line,
  .mh-caption-line {
    white-space: normal;
    overflow-wrap: break-word;
  }

  /* Pareto: title intro overlay, then scaled counters + chart */
  .anim-header {
    position: absolute;
    inset: 0;
    z-index: 10;
    margin: 0;
    max-width: none;
    padding: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    animation: mobile-fade-out 0.5s 2.8s ease-in forwards;
  }

  .anim-title { font-size: clamp(28px, 5.5vw, 38px); }

  .pareto-counters,
  .pareto-chart {
    opacity: 0;
    animation: mobile-fade-in 0.5s 3.0s ease-out forwards;
  }

  .pareto-counter-value { font-size: clamp(26px, 5.5vw, 64px); }

  .pareto-counters {
    gap: clamp(20px, 8vw, 96px);
    margin-bottom: 12px;
  }
}

/* Reduced-motion on mobile: skip intro animations, show content immediately */
@media (max-width: 559px) and (prefers-reduced-motion: reduce) {
  .milp-mobile-intro { display: none; animation: none; }
  .milp-wrap { animation: none; opacity: 1; }

  .anim-header {
    animation: none;
    position: relative;
    inset: auto;
    max-width: 580px;
    margin-bottom: 24px;
    padding: 0;
    z-index: auto;
    display: block;
  }

  .pareto-counters,
  .pareto-chart {
    animation: none;
    opacity: 1;
  }
}
