#tcprto_wrapper {
  --tcprto-bg:         var(--surface-page);
  --tcprto-surface:    var(--surface-card);
  --tcprto-border:     var(--border);
  --tcprto-text:       var(--text-primary);
  --tcprto-muted:      var(--text-muted);
  --tcprto-shadow:     var(--shadow-card-color);
  --tcprto-rtt:        var(--data-rtt);       --tcprto-rtt-ink:  var(--data-rtt-ink);
  --tcprto-srtt:       var(--data-srtt);      --tcprto-srtt-ink: var(--data-srtt-ink);
  --tcprto-var:        var(--data-var);       --tcprto-var-ink:  var(--data-var-ink);
  --tcprto-rto:        var(--data-rto);       --tcprto-rto-ink:  var(--data-rto-ink);
  --tcprto-gap:        var(--data-gap);       --tcprto-gap-ink:  var(--data-gap-ink);
  /* faded "prev" variants — same hue, washed out bg, muted ink */
  --tcprto-rtt-p:      var(--data-rtt-prev);  --tcprto-rtt-p-ink:  var(--data-rtt-prev-ink);
  --tcprto-srtt-p:     var(--data-srtt-prev); --tcprto-srtt-p-ink: var(--data-srtt-prev-ink);
  --tcprto-var-p:      var(--data-var-prev);  --tcprto-var-p-ink:  var(--data-var-prev-ink);
  --tcprto-gap-p:      var(--data-gap-prev);  --tcprto-gap-p-ink:  var(--data-gap-prev-ink);
  --tcprto-accent:     var(--accent);
  --tcprto-random:     var(--data-check);
    --tcprto-radius:     var(--card-radius);
  --tcprto-mono:       var(--font-mono);
  --tcprto-ui:         var(--font-nomono);
  /* formula grid: label col + eq col + content col */
  --tcprto-label-w:    58px;
    --tcprto-row-h:      2rem;   /* consistent row height throughout formulas */

  font-family: var(--tcprto-ui);
  background: var(--tcprto-bg);
  color: var(--tcprto-text);
  /* The browser's own scroll-anchoring (on by default in Chrome/Firefox)
     also reacts to the accordion steps above resizing during their 0.3s
     open/close, nudging the scroll position mid-transition on top of the
     precise compensating scroll tcprto_addStep/tcprto_addRandom already do
     in JS — two adjustments instead of one. Opting this tool's whole
     subtree out leaves just the deliberate one. */
  overflow-anchor: none;
  /* No top padding — the shared .main-content-placeholder margin already
     gives every tool page the same gap below the nav; adding more here on
     top of that made this tool's first card sit further down than the
     others. Side/bottom padding come from the same shared tokens the other
     three tools use (base/layout.css) so the inset from the screen edge
     matches everywhere, not just the amount left over below the nav. */
  padding: 0 var(--tool-padding-x) var(--tool-padding-bottom);
  min-height: 100vh;
  box-sizing: border-box;
}
#tcprto_wrapper *, #tcprto_wrapper *::before, #tcprto_wrapper *::after { box-sizing: border-box; }

.tcprto_container { max-width: 680px; margin: 0 auto; }

/* ── Legend (collapsible) ── */
.tcprto_legend_wrap {
  margin-bottom: 24px;
  background: var(--tcprto-surface);
  border: 1px solid var(--tcprto-border);
  border-radius: var(--tcprto-radius);
  box-shadow: 0 2px 8px var(--tcprto-shadow);
  overflow: hidden;
}
.tcprto_legend_toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 12px 16px;
  background: none;
  border: none;
  cursor: pointer;
  font-family: var(--tcprto-ui);
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--tcprto-muted);
  text-align: left;
  transition: background 0.15s;
}
.tcprto_legend_toggle:hover { background: var(--accent-soft); }
.tcprto_legend_toggle_chevron {
  width: 16px; height: 16px; margin-left: auto; flex-shrink: 0;
  transition: transform 0.25s cubic-bezier(.4,0,.2,1);
  color: var(--tcprto-muted);
}
.tcprto_legend_wrap.tcprto_legend_open .tcprto_legend_toggle_chevron { transform: rotate(180deg); }
/* Animated open/close at the same 0.3s ease the rest of the site uses for
   the mobile menu slide, the info panel fade, and the congestion
   visualizer's settings/legend panels. display:none can't transition, so
   this collapses via max-height + opacity with overflow:hidden instead,
   staying laid out (display:block) the whole time. max-height is a
   generous fixed cap, not the content's real height — CSS can't animate to
   "auto" — sized to comfortably clear this panel's tallest state. */
.tcprto_legend_body {
  display: block;
  padding: 0 16px;
  border-top: 1px solid var(--tcprto-border);
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  border-top-color: transparent;
  transition: max-height 0.3s ease, opacity 0.3s ease, padding 0.3s ease, border-top-color 0.3s ease;
}
.tcprto_legend_wrap.tcprto_legend_open .tcprto_legend_body {
  padding: 4px 16px 14px;
  max-height: 600px;
  opacity: 1;
  border-top-color: var(--tcprto-border);
}
.tcprto_legend_item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: 0.79rem;
  font-family: var(--tcprto-mono);
  line-height: 1.55;
  padding: 7px 0;
  border-bottom: 1px solid var(--tcprto-border);
}
.tcprto_legend_item:last-child { border-bottom: none; }
.tcprto_legend_lbl  { flex-shrink: 0; min-width: 46px; }
.tcprto_legend_desc { color: var(--tcprto-muted); }
.tcprto_legend_desc strong { color: var(--tcprto-text); font-weight: 700; }

/* ── Pills ── */
.tcprto_pill {
  display: inline-flex; align-items: center;
  padding: 0 7px;
  height: 1.5em;
  border-radius: 99px;
  font-family: var(--tcprto-mono);
  font-weight: 700;
  font-size: 0.85em;
  white-space: nowrap;
  vertical-align: middle;
  line-height: 1;
}
.tcprto_pill_rtt  { background: var(--tcprto-rtt);  color: var(--tcprto-rtt-ink); }
.tcprto_pill_srtt { background: var(--tcprto-srtt); color: var(--tcprto-srtt-ink); }
.tcprto_pill_var  { background: var(--tcprto-var);  color: var(--tcprto-var-ink); }
.tcprto_pill_rto  { background: var(--tcprto-rto);  color: var(--tcprto-rto-ink); }
.tcprto_pill_gap  { background: var(--tcprto-gap);  color: var(--tcprto-gap-ink); }
/* darker "prev" variants */
.tcprto_pill_rtt_p  { background: var(--tcprto-rtt-p);  color: var(--tcprto-rtt-p-ink); }
.tcprto_pill_srtt_p { background: var(--tcprto-srtt-p); color: var(--tcprto-srtt-p-ink); }
.tcprto_pill_var_p  { background: var(--tcprto-var-p);  color: var(--tcprto-var-p-ink); }
.tcprto_pill_gap_p  { background: var(--tcprto-gap-p);  color: var(--tcprto-gap-p-ink); }

/* ── Accordion list ── */
.tcprto_steps { display: flex; flex-direction: column; gap: 10px; margin-bottom: 24px; }

.tcprto_step {
  background: var(--tcprto-surface);
  border: 1px solid var(--tcprto-border);
  border-radius: var(--tcprto-radius);
  overflow: hidden;
  box-shadow: 0 2px 8px var(--tcprto-shadow);
  transition: box-shadow 0.2s;
}
.tcprto_step:hover { box-shadow: var(--shadow-lg); }

/* Deleting the last step (trash icon) is two separate stages, run one after
   the other by tcprto_deleteLast — not one combined transition:
     1. tcprto_step_fading  — opacity only, card keeps its full height. On
        an OPEN step (the tall, expanded case), doing this before the
        collapse below matters: collapsing height at the same time as the
        fade would reflow everything beneath the card immediately, masking
        the fade under that motion.
     2. tcprto_step_collapsing — height/margin/border to 0, now that the
        card is already invisible. This is the part that actually moves the
        rest of the page, and it only starts after the fade has had a
        moment to register on its own.
   0.5s total (0.25s fade + a 0.1s pause + 0.15s collapse, timed in JS) —
   slower than the 0.3s accordion open/close elsewhere in this tool, so
   deleting reads as a distinct, more deliberate action. `height` (not
   max-height) animates from a JS-measured starting value, set inline by
   tcprto_deleteLast right before stage 2's class is added. */
.tcprto_step.tcprto_step_fading {
  transition: opacity 0.25s ease;
  opacity: 0;
}
.tcprto_step.tcprto_step_collapsing {
  overflow: hidden;
  transition: height 0.15s ease, margin 0.15s ease, border-width 0.15s ease;
  opacity: 0;
  height: 0 !important;
  margin: 0;
  border-width: 0;
}

/* header row: num · [toggle zone: tag + summary] · trash · chevron — all one line */
.tcprto_step_header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 14px 13px 16px;
  user-select: none;
  background: none;
  width: 100%;
  transition: background 0.15s;
}
.tcprto_step_header:hover { background: var(--accent-soft); }

/* the clickable toggle zone fills available space */
.tcprto_step_toggle {
  flex: 1;
  min-width: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
}

.tcprto_step_num {
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--tcprto-bg); border: 2px solid var(--tcprto-border);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.75rem; font-weight: 800; color: var(--tcprto-muted);
  flex-shrink: 0; font-family: var(--tcprto-mono);
  transition: border-color 0.2s, color 0.2s;
}
.tcprto_step.tcprto_open .tcprto_step_num { border-color: var(--tcprto-accent); color: var(--tcprto-accent); }

.tcprto_step_summary {
  flex: 1;
  min-width: 0;
  font-size: 0.86rem; font-weight: 600; color: var(--tcprto-text);
  display: flex; align-items: center; gap: 7px; flex-wrap: nowrap; overflow: hidden;
}
.tcprto_step_summary .tcprto_h_rtt,
.tcprto_step_summary .tcprto_h_rto { flex-shrink: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.tcprto_step_tag {
  font-size: 0.68rem; font-weight: 700; color: var(--tcprto-muted);
  text-transform: uppercase; letter-spacing: 0.06em;
  background: var(--tcprto-bg); padding: 2px 6px;
  border-radius: 4px; border: 1px solid var(--tcprto-border);
  flex-shrink: 0;
  /* Anchor for the ::after peek overlay used at narrow widths. */
  position: relative;
}

/* Wide screens: the full stage name, exactly as before. The single-letter
   spelling and the peek overlay are narrow-screen-only (see the media query
   at the bottom of this file). */
.tcprto_tag_abbr { display: none; }

/* The full word, revealed over the summary row when the collapsed I/B/O tag
   is tapped (or hovered / keyboard-focused). Absolutely positioned and
   vertically centered on the tag so it floats above the RTT/RTO pills to its
   right instead of widening the row — the row is already tight at this width,
   which is why the tag was abbreviated in the first place. It stays inside
   .tcprto_step_header's own height, so .tcprto_step's overflow:hidden (needed
   for the accordion animation) never clips it. */
.tcprto_step_tag::after {
  content: attr(data-tag);
  position: absolute;
  left: -1px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  white-space: nowrap;
  padding: 2px 6px;
  border-radius: 4px;
  border: 1px solid var(--tcprto-border);
  background: var(--tcprto-surface);
  color: var(--tcprto-text);
  box-shadow: 0 2px 8px var(--tcprto-shadow);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease;
}

/* trash button — only shown on last deletable step */
.tcprto_trash_btn {
  display: none; /* shown via JS on last step */
  align-items: center; justify-content: center;
  width: 28px; height: 28px;
  flex-shrink: 0;
  background: none; border: none; border-radius: 6px;
  cursor: pointer; color: var(--tcprto-muted);
  transition: background 0.15s, color 0.15s;
  padding: 0;
}
.tcprto_trash_btn:hover { background: var(--tcprto-rto); color: var(--tcprto-rto-ink); }
.tcprto_trash_btn svg { width: 15px; height: 15px; }
/* stop click from toggling the accordion */
.tcprto_trash_btn { pointer-events: all; }

.tcprto_chevron {
  width: 18px; height: 18px; flex-shrink: 0;
  transition: transform 0.25s cubic-bezier(.4,0,.2,1);
  color: var(--tcprto-muted);
}
.tcprto_step.tcprto_open .tcprto_chevron { transform: rotate(180deg); }

/* Same animated-collapse approach as .tcprto_legend_body above. Steps hold
   the most content of anything in this tool (an "ongoing" step has 5
   var-blocks), so the max-height cap is the most generous of the two. */
.tcprto_step_body {
  display: block;
  padding: 0 18px;
  border-top: 1px solid var(--tcprto-border);
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  border-top-color: transparent;
  transition: max-height 0.3s ease, opacity 0.3s ease, padding 0.3s ease, border-top-color 0.3s ease;
}
.tcprto_step.tcprto_open .tcprto_step_body {
  padding: 0 18px 20px;
  max-height: 900px;
  opacity: 1;
  border-top-color: var(--tcprto-border);
}

/* ── Formula blocks ──
   Layout per var-block:

     VAR  =  (¾ × VARprev) + (¼ × GAP)
          =  (¾ × 28.2ms) + (¼ × 9ms)
          =  (21.2 + 2.3)
          =  23.4ms

   Each row is: [left-indent] ["= "] [content]
   Line 0: left-indent = pill label; no "= " prefix; content = first formula line
   Line 1+: left-indent = blank (same width as pill); "= " prefix; content

   All "=" signs align because the indent col is always the same fixed width.
*/
.tcprto_vars {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-top: 14px;
  font-family: var(--tcprto-mono);
  font-size: 0.87rem;
}

.tcprto_var_block { display: flex; flex-direction: column; }

.tcprto_vline {
  display: flex;
  align-items: center;
  min-height: var(--tcprto-row-h);
}

/* Fixed-width left column — same for every row in the block */
.tcprto_vline_indent {
  width: var(--tcprto-label-w);
  flex-shrink: 0;
  display: flex;
  align-items: center;
}

/* The "= " that appears before continuation lines — fixed width so content aligns */
.tcprto_vline_eq {
  flex-shrink: 0;
  width: 1.6em;
  color: var(--tcprto-muted);
  font-weight: 400;
}

.tcprto_vline_content {
  flex: 1;
  color: var(--tcprto-text);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
  line-height: 1.4;
}
.tcprto_vline_content.tcprto_final { font-weight: 700; }

.tcprto_op { color: var(--tcprto-muted); padding: 0 1px; }  /* ×  +  −  /  |  ( ) */

.tcprto_na { color: var(--tcprto-muted); font-style: italic; }

.tcprto_measured_note {
  color: var(--tcprto-muted);
  font-size: 0.78em;
  font-style: italic;
  margin-left: 2px;
}

.tcprto_gap_sep { height: 1px; background: var(--tcprto-border); margin: 4px 0 6px; }

/* ── Input area ── */
.tcprto_input_area {
  background: var(--tcprto-surface);
  border: 1px solid var(--tcprto-border);
  border-radius: var(--tcprto-radius);
  padding: 18px 20px;
  box-shadow: 0 2px 8px var(--tcprto-shadow);
}
.tcprto_input_lbl { display: block; font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--tcprto-muted); margin-bottom: 10px; }
.tcprto_input_row { display: flex; gap: 8px; align-items: stretch; }
.tcprto_input_wrap { position: relative; flex: 1; min-width: 0; }
.tcprto_input_wrap::after { content:'ms'; position:absolute; right:11px; top:50%; transform:translateY(-50%); font-family:var(--tcprto-mono); font-size:0.78rem; color:var(--tcprto-muted); pointer-events:none; }
.tcprto_num_input {
  width:100%; padding:10px 32px 10px 12px;
  border:1.5px solid var(--tcprto-border); border-radius:8px;
  font-family:var(--tcprto-mono); font-size:0.98rem; font-weight:600;
  color:var(--tcprto-text); background:var(--tcprto-bg);
  outline:none; transition:border-color 0.15s;
  -moz-appearance:textfield;
}
.tcprto_num_input::-webkit-inner-spin-button, .tcprto_num_input::-webkit-outer-spin-button { -webkit-appearance:none; }
.tcprto_num_input:focus { border-color:var(--tcprto-accent); background:var(--tcprto-surface); }

.tcprto_calc_btn {
  padding:10px 18px; background:var(--tcprto-accent); color:var(--text-on-accent);
  border:none; border-radius:8px; font-family:var(--tcprto-ui);
  font-size:0.87rem; font-weight:700; cursor:pointer;
  transition:background 0.15s,transform 0.1s; white-space:nowrap;
}
.tcprto_calc_btn:hover { background:var(--accent-strong); }
.tcprto_calc_btn:active { transform:scale(.97); }

.tcprto_rand_btn {
  padding:10px 14px; background:transparent;
  color:var(--tcprto-random); border:1.5px solid var(--tcprto-random);
  border-radius:8px; font-family:var(--tcprto-ui);
  font-size:0.87rem; font-weight:700; cursor:pointer;
  transition:background 0.15s,color 0.15s,transform 0.1s; white-space:nowrap;
  display:flex; align-items:center; gap:5px;
}
.tcprto_rand_btn:hover { background:var(--tcprto-random); color:var(--text-on-accent); }
.tcprto_rand_btn:active { transform:scale(.97); }
.tcprto_rand_btn svg { width:13px; height:13px; flex-shrink:0; }

.tcprto_error { color:var(--tcprto-rto-ink); font-size:0.78rem; font-family:var(--tcprto-mono); margin-top:8px; display:none; }

/* header summary pills */
.tcprto_h_rto { font-family:var(--tcprto-mono); font-size:0.82rem; color:var(--tcprto-rto-ink); background:var(--tcprto-rto); padding:2px 8px; border-radius:99px; font-weight:700; }
.tcprto_h_arr { color:var(--tcprto-muted); font-size:0.82rem; }
.tcprto_h_rtt { font-family:var(--tcprto-mono); font-size:0.82rem; color:var(--tcprto-rtt-ink); background:var(--tcprto-rtt); padding:2px 8px; border-radius:99px; font-weight:700; }

/* ── Narrow screens: collapse the stage tag to its first letter ──
   "INITIAL"/"BOOTSTRAP"/"ONGOING" plus the RTT → RTO pills don't fit on one
   line on a phone, and .tcprto_step_summary is nowrap with ellipsis, so the
   pills — the actual numbers being demonstrated — were the part getting cut
   off. Showing just I/B/O buys that width back; the full word is one tap
   (or hover / keyboard focus) away via the ::after overlay defined above.
   Keep this breakpoint in sync with TAG_ABBR_BP in
   assets/js/tools/tcp-rto-calculator.js, which uses it to decide whether a
   tap opens the overlay or falls through to the accordion toggle. */
@media(max-width:640px){
  .tcprto_tag_full { display: none; }
  .tcprto_tag_abbr { display: inline; }

  .tcprto_step_tag {
    cursor: pointer;
    /* I is much narrower than B/O — a floor keeps all three the same width so
       the pills beside them start at the same x from row to row. */
    min-width: 24px;
    text-align: center;
  }

  .tcprto_step_tag:hover::after,
  .tcprto_step_tag:focus-visible::after,
  .tcprto_step_tag.tcprto_tag_peeking::after {
    opacity: 1;
    visibility: visible;
  }
}

@media(max-width:520px){
  #tcprto_wrapper{padding:18px 10px 36px;}
  .tcprto_vars{font-size:0.78rem;}
  .tcprto_input_row{flex-wrap:wrap;}
  .tcprto_input_wrap{min-width:100%;}
}
