/* HourlyVPS pricing widgets: "Pull the tape", plan table, price ladder, duration cards.
   Loaded only on views that print them (inc/assets.php, hvps_theme_needs_widgets()); the
   components enqueue it late as a fallback anywhere else. */

/* ---------- Pull the tape ----------
   The tape sits in columns from about 250px to 1280px wide (phone, half-width hero, guide
   column, full width), so its layout follows its own width: it is the size container
   "tape". Base rules are the narrow layout, the >=720px viewport block widens it, and the
   @container block after it narrows it again whenever the tape's own column is narrow. */
.tape{--tw:26px;container:tape/inline-size;display:grid;grid-template-columns:minmax(0,1fr);gap:1.25rem;padding:clamp(1.125rem,3vw,2rem);background:var(--surface);border:1px solid var(--rule);border-radius:6px}
.tape__head{display:grid;grid-template-columns:minmax(0,1fr);gap:.75rem}
.tape__head>*{margin:0}
.tape__title{font-size:clamp(1.375rem,2.4vw,1.75rem);font-size:clamp(1.375rem,5cqi,1.75rem)}
.tape__intro{color:var(--muted)}
.tape__plan{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}
.tape__plan label{font-size:.875rem;color:var(--muted)}
.tape__plan select{flex:1 1 14rem;min-width:0;max-width:100%}
/* The no-JS "Show cost" button: hidden from first paint when JS runs (html.js is set in the head). */
.js .tape__go,.tape.is-live .tape__go{display:none}
.tape__readout{display:flex;flex-wrap:wrap;align-items:baseline;gap:.25rem .875rem;min-height:3.25rem}
.tape__dur{font-size:clamp(2rem,4.5vw,3rem);font-size:clamp(2rem,8cqi,3rem);font-weight:700;line-height:1.05;letter-spacing:-.02em}
.tape__rail{position:relative;container:rail/inline-size;padding:1.625rem 0 .25rem}
.tape__strip{position:absolute;left:calc(var(--tw) / 2);right:calc(var(--tw) / 2);top:calc(1.625rem + 8px);height:36px;overflow:hidden;border-radius:2px;background:repeating-linear-gradient(90deg,var(--on-tape) 0 1px,transparent 1px calc(100% / var(--n))) 0 0/100% 30% no-repeat,var(--tape);box-shadow:inset 0 0 0 1.5px var(--tape-edge)}
.tape__tick{position:absolute;top:0;left:calc(var(--i) / var(--n) * 100%);width:1.5px;height:55%;background:var(--on-tape)}
.tape__cover{position:absolute;inset:0;background:var(--surface-2);box-shadow:inset 0 1px 0 var(--rule),inset 0 -1px 0 var(--rule),inset 2px 0 0 var(--muted);transform:translateX(calc(var(--p) * 100%))}
.tape__range{position:relative;z-index:2;display:block;width:100%;height:52px;margin:0;padding:0;background:transparent;cursor:pointer;-webkit-appearance:none;appearance:none}
.tape__range::-webkit-slider-runnable-track{height:52px;background:transparent;border:0}
.tape__range::-moz-range-track{height:52px;background:transparent;border:0}
.tape__range::-webkit-slider-thumb{width:var(--tw);height:52px;border:2px solid var(--tape-edge);border-radius:3px;background:linear-gradient(90deg,var(--tape) 0 calc(50% - 1px),var(--on-tape) calc(50% - 1px) calc(50% + 1px),var(--tape) calc(50% + 1px));box-shadow:0 2px 0 var(--tape-edge);-webkit-appearance:none;appearance:none}
.tape__range::-moz-range-thumb{box-sizing:border-box;width:var(--tw);height:52px;border:2px solid var(--tape-edge);border-radius:3px;background:linear-gradient(90deg,var(--tape) 0 calc(50% - 1px),var(--on-tape) calc(50% - 1px) calc(50% + 1px),var(--tape) calc(50% + 1px));box-shadow:0 2px 0 var(--tape-edge)}
.tape__range:focus-visible{outline:2px solid var(--focus);outline-offset:4px}
.tape__notches{position:absolute;z-index:1;left:calc(var(--tw) / 2);right:calc(var(--tw) / 2);top:0;height:calc(1.625rem + 44px);pointer-events:none}
.tape__notch{position:absolute;top:0;bottom:0;left:calc(var(--i) / var(--n) * 100%);border-left:2px solid var(--notch)}
.tape__notch span{position:absolute;top:0;left:4px;font:400 .75rem/1 var(--mono);color:var(--muted);white-space:nowrap}
.tape__notch[data-notch=cap]{border-left-color:var(--cap)}
.tape__notch[data-notch=cap] span{left:auto;right:4px;color:var(--cap);font-weight:600}
/* Hours past the monthly cap in the first billing month: hatched, they are not charged. */
.tape__free{position:absolute;top:0;bottom:0;left:calc(var(--i) / var(--n) * 100%);width:calc((var(--j) - var(--i)) / var(--n) * 100%);background:repeating-linear-gradient(135deg,var(--on-tape) 0 1.5px,transparent 1.5px 7px);opacity:.35}
.tape__scale{position:relative;height:1.25rem;margin:.375rem calc(var(--tw) / 2) 0;font:400 .75rem/1.25rem var(--mono);color:var(--muted)}
.tape__scale span{position:absolute;left:calc(var(--i) / var(--n) * 100%);transform:translateX(-50%);white-space:nowrap}
.tape__scale span:first-child{transform:none}
.tape__scale span:last-child{transform:translateX(-100%)}
.tape__presets{display:flex;flex-wrap:wrap;gap:.5rem}
.tape__modes{display:grid;gap:.5rem;margin:0;padding:0;list-style:none}
.tape__mode{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:baseline;gap:.125rem .75rem;margin:0;padding:.75rem 1rem;border:1.5px solid var(--rule);border-radius:var(--r);background:var(--bg)}
.tape__mode-name{display:flex;align-items:center;gap:.375rem;font-weight:600}
.tape__mode-name .icon{width:1.25rem;height:1.25rem;color:var(--muted)}
.tape__cost{grid-row:1/span 2;grid-column:2;align-self:center;font-size:1.625rem;font-weight:700;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.tape__calc{font:400 .8125rem/1.45 var(--mono);color:var(--muted)}
.tape__mode.is-best{border-color:var(--tape-edge);box-shadow:inset 6px 0 0 var(--tape)}
.tape__best{justify-self:start;margin-top:.25rem;padding:0 .5rem;border:1px solid var(--tape-edge);border-radius:2px;background:var(--tape);color:var(--on-tape);font-size:.75rem;font-weight:650;line-height:1.6}
/* Equal totals (e.g. a short job under the hourly-capped refund rule): no single winner, so
   the tied cards get a neutral "Same total" tag instead of the yellow "Lowest". */
.tape__mode.is-tie{border-color:var(--ink)}
.tape__mode.is-tie .tape__best{background:var(--surface);border-color:var(--ink);color:var(--ink)}
/* Result: one cost on the meter, the working, hours billed and the cap. */
.tape__result{display:grid;gap:.375rem;padding:1rem 1.125rem 1.125rem;border:1.5px solid var(--tape-edge);border-radius:var(--r);background:var(--bg);box-shadow:inset 6px 0 0 var(--tape)}
.tape__result>*{margin:0}
.tape__total{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem .875rem}
.tape__result .tape__cost{font-size:clamp(2rem,2rem + 2cqi,2.75rem);font-weight:700;line-height:1.1;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.tape__badge{padding:.125rem .5rem;border:1.5px solid var(--cap);border-radius:2px;color:var(--cap);font-size:.8125rem;font-weight:650;line-height:1.4}
.tape__result.is-capped{box-shadow:inset 6px 0 0 var(--cap)}
.tape__result .tape__calc{overflow-wrap:anywhere}
.tape__facts{display:grid;gap:.25rem;margin-top:.5rem;padding-top:.625rem;border-top:1px solid var(--rule);font-size:.875rem}
.tape__facts div{display:flex;flex-wrap:wrap;gap:0 .5rem}
@container tape (min-width:28rem){.tape__facts div{display:grid;grid-template-columns:7.5rem minmax(0,1fr)}.tape__facts dt::after{content:none}}
.tape__facts dt{color:var(--muted)}
.tape__facts dt::after{content:":"}
.tape__facts dd{margin:0;font-weight:600}
.tape__foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:1rem}
.tape__deploy:empty{display:none}
.tape__exact{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem 1rem}
.tape__exact legend{margin-bottom:.375rem;font-size:.875rem;font-weight:600;color:var(--muted)}
.tape__field{display:inline-flex;align-items:center;gap:.375rem}
.tape__field input{width:4.75rem;font-family:var(--mono)}
.tape__field label{font-size:.875rem;font-weight:400}
.tape__notes{margin:0;padding:1rem 0 0;list-style:none;border-top:1px solid var(--rule);font-size:.875rem;color:var(--muted)}
.tape__notes li+li{margin-top:.375rem}
.tape>.ph-flag{justify-self:start;margin:0}
.tape--empty{padding:1.5rem;border:1px dashed var(--rule);border-radius:6px;color:var(--muted)}
@media (min-width:720px){
.tape__head{grid-template-columns:minmax(0,1fr) auto;align-items:end}
.tape__plan{grid-column:2;grid-row:1/span 2}
.tape__plan select{flex:0 1 auto}
.tape__modes{grid-template-columns:repeat(3,minmax(0,1fr))}
.tape__mode{grid-template-columns:1fr;align-content:start;padding:1rem 1.125rem 1.125rem}
.tape__cost{grid-row:auto;grid-column:auto;font-size:1.875rem;margin-top:.25rem}
.tape__mode.is-best{box-shadow:inset 0 6px 0 var(--tape)}
.tape__best{position:absolute;top:-.6875rem;right:.625rem;margin:0}
}
/* Narrow tape column (phone, half-width hero below ~1300px): one-column head, chips in an
   even grid, mode cards as rows (name and working on the left, total on the right). */
@container tape (max-width:33.99rem){
.tape__head{grid-template-columns:minmax(0,1fr);align-items:normal}
.tape__plan{grid-column:auto;grid-row:auto}
.tape__plan select{flex:1 1 14rem}
.tape__presets{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}
.tape__presets .chip{justify-content:center;padding-inline:.5rem}
.tape__modes{grid-template-columns:minmax(0,1fr)}
.tape__mode{grid-template-columns:minmax(0,1fr) auto;align-content:normal;padding:.75rem 1rem}
.tape__cost{grid-row:1/span 2;grid-column:2;margin-top:0;font-size:1.625rem}
.tape__mode.is-best{box-shadow:inset 6px 0 0 var(--tape)}
.tape__best{position:static;margin-top:.25rem}
}
@container tape (max-width:19.99rem){.tape__cost{font-size:1.375rem}}
@container tape (max-width:16.99rem){.tape__presets{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* Scale labels follow the rail's own width (the calculator reuses the rail): below 30rem
   only 1 h, 1 d, 14 d and 3 mo are printed, so neighbours never collide. */
@container rail (max-width:29.99rem){.tape__scale span:nth-child(2),.tape__scale span:nth-child(3),.tape__scale span:nth-child(5){display:none}}

/* ---------- Plan table (CSS-only Hour | Day | Month) ---------- */
.plans{position:relative}
.plans__radio{position:absolute;width:1px;height:1px;margin:0;opacity:0;pointer-events:none}
.plans__bar{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem 1rem;margin-bottom:1rem}
.plans__bar .ph-flag{margin:0}
.plans__bar-note{margin:0;font-size:.875rem;color:var(--muted)}
.seg{display:inline-flex;gap:2px;padding:3px;border:1.5px solid var(--ink);border-radius:6px;background:var(--surface)}
.seg__opt{display:inline-flex;align-items:center;min-height:38px;padding:0 1rem;border-radius:3px;font-weight:600;cursor:pointer;-webkit-user-select:none;user-select:none}
.seg__opt:hover{background:var(--surface-2)}
.plans__radio--hour:checked~.plans__bar .seg__opt--hour,.plans__radio--day:checked~.plans__bar .seg__opt--day,.plans__radio--month:checked~.plans__bar .seg__opt--month{background:var(--ink);color:var(--bg)}
.plans__radio--hour:focus-visible~.plans__bar .seg__opt--hour,.plans__radio--day:focus-visible~.plans__bar .seg__opt--day,.plans__radio--month:focus-visible~.plans__bar .seg__opt--month{outline:2px solid var(--focus);outline-offset:2px}
.pt{width:100%;border-collapse:separate;border-spacing:0;background:var(--surface);border:1px solid var(--rule);border-radius:6px;font-variant-numeric:tabular-nums}
.pt__caption{padding-bottom:.75rem;text-align:left;font-weight:600}
.pt th,.pt td{padding:.875rem 1rem;border-bottom:1px solid var(--rule);text-align:left;vertical-align:middle}
.pt thead th{padding-block:.625rem;font-size:.8125rem;font-weight:600;color:var(--muted)}
.pt tbody tr:last-child>*{border-bottom:0}
.pt tbody tr:hover{background:var(--bg)}
.pt__plan{font-weight:650;white-space:nowrap}
.pt__link{color:inherit;text-decoration:none}
.pt__link:hover .pt__name{text-decoration:underline}
.pt__code{margin-left:.25rem;padding:0 .3125rem;border:1px solid var(--ink);border-radius:2px;font:600 .8125rem/1.5 var(--mono)}
.pt__sub{display:block;margin-top:.125rem;font-size:.8125rem;font-weight:400;color:var(--muted);white-space:nowrap}
.pt__price{min-width:9.5rem}
.pt__prices{display:flex;flex-direction:column;gap:.125rem}
.pt td .mono{white-space:nowrap}
.price{font-size:.8125rem;color:var(--muted);white-space:nowrap}
.price b{font-weight:600;color:var(--ink)}
.plans__radio--hour:checked~.plans__body .price--hour,.plans__radio--day:checked~.plans__body .price--day,.plans__radio--month:checked~.plans__body .price--month{order:-1;font-size:.9375rem;color:var(--ink)}
.plans__radio--hour:checked~.plans__body .price--hour b,.plans__radio--day:checked~.plans__body .price--day b,.plans__radio--month:checked~.plans__body .price--month b{font-size:1.375rem;font-weight:700;letter-spacing:-.01em}
.pt__go{text-align:right;white-space:nowrap}
.plans__notes{margin:1rem 0 0;padding:0;list-style:none;font-size:.875rem;color:var(--muted)}
.plans__notes li+li{margin-top:.25rem}
.plans--empty{padding:1.5rem;border:1px dashed var(--rule);border-radius:6px;color:var(--muted)}
.plans__body{overflow-x:auto}
@media (min-width:720px) and (max-width:1023px){.pt th,.pt td{padding:.75rem .5rem}.pt tr>:first-child{padding-left:.875rem}.pt tr>:last-child{padding-right:.875rem}.pt__sub{white-space:normal}.pt__price{min-width:0}.pt__plan{white-space:normal}}
@media (max-width:719px){
.plans__bar{position:sticky;top:0;z-index:5;margin-inline:calc(var(--gx) * -1);padding:.5rem var(--gx);background:var(--bg)}
.pt,.pt tbody,.pt tr,.pt th,.pt td{display:block}
.pt{border:0;border-radius:0;background:none}
.pt thead{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
.pt tr{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:.75rem 1rem;margin-bottom:.75rem;padding:1rem;background:var(--surface);border:1px solid var(--rule);border-radius:6px}
.pt tbody tr:hover{background:var(--surface)}
.pt th,.pt td{padding:0;border:0}
.pt__price{grid-column:2;grid-row:1;min-width:0;text-align:right}
.pt__prices{align-items:flex-end}
.pt td[data-label]::before{content:attr(data-label);display:block;font-size:.75rem;font-weight:600;color:var(--muted)}
.pt__sub{white-space:normal}
.pt__go{grid-column:1/-1;text-align:left}
.pt caption{display:block}
.pt__deploy{width:100%;min-height:44px}
}

/* ---------- Price ladder: one billing month on the meter, drawn to scale ---------- */
.ladder{display:grid;gap:1.25rem;margin:0}
.ladder__rule{position:relative;display:flex;height:64px;margin-top:2rem;border-radius:2px;background:var(--tape);box-shadow:inset 0 0 0 1.5px var(--tape-edge)}
.ladder__rule::after{content:"";position:absolute;inset:0;background:repeating-linear-gradient(90deg,var(--on-tape) 0 1px,transparent 1px calc(100% / var(--n))) 0 0/100% 24% no-repeat;pointer-events:none}
.ladder__zone{position:relative;min-width:0;color:var(--on-tape)}
.ladder__zone--meter{flex:0 0 calc(var(--c) * 100%)}
.ladder__zone--cap{flex:1 1 0;border-radius:0 2px 2px 0;background:repeating-linear-gradient(135deg,transparent 0 6px,var(--rule) 6px 7.5px),var(--surface-2);box-shadow:inset 0 0 0 1.5px var(--tape-edge);color:var(--ink)}
.ladder__zone span{position:absolute;left:.625rem;bottom:.5rem;font-size:.9375rem;font-weight:650;white-space:nowrap}
.ladder__notch{position:absolute;z-index:1;top:-1.75rem;bottom:55%;left:calc(var(--x) * 100%);border-left:2px solid var(--notch)}
.ladder__notch span{position:absolute;top:0;left:5px;font:400 .75rem/1 var(--mono);color:var(--muted);white-space:nowrap}
.ladder__notch--cap{border-left-color:var(--cap)}
.ladder__notch--cap span{left:auto;right:5px;color:var(--cap);font-weight:600}
.ladder__scale{position:relative;height:1.25rem;margin-top:-.75rem;font:400 .75rem/1.25rem var(--mono);color:var(--muted)}
.ladder__scale span{position:absolute;left:calc(var(--x) * 100%);transform:translateX(-50%);white-space:nowrap}
.ladder__scale span:first-child{transform:none}
.ladder__scale span:last-child{transform:translateX(-100%)}
.ladder__legend{display:grid;gap:1rem;margin:0;padding:0;list-style:none}
.ladder__item{margin:0;display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:.75rem;align-content:start;padding-top:.875rem;border-top:3px solid var(--ink)}
.ladder__item--month{border-top-color:var(--cap)}
.ladder__item .icon{grid-row:1/span 3;width:1.75rem;height:1.75rem}
.ladder__mode{font-size:1.125rem;font-weight:650}
.ladder__price{font:400 .875rem/1.5 var(--mono)}
.ladder__range{color:var(--muted);font-size:.9375rem}
.ladder__cap{font-size:.875rem;color:var(--muted)}
@media (min-width:720px){.ladder__legend{grid-template-columns:repeat(3,minmax(0,1fr));gap:1.5rem}}
@media (max-width:719px){.ladder__zone--cap span,.ladder__notch--day span,.ladder__notch--week span{display:none}.ladder__scale span:nth-child(n+2):nth-last-child(n+2){display:none}}

/* ---------- Duration cards: each job drawn to scale (a 24-hour day, or one billing month with the cap) ---------- */
.dcards{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,15rem),1fr));gap:1rem;margin:0;padding:0;list-style:none}
.dcard{display:grid;align-content:start;gap:.625rem;margin:0;padding:1.25rem;background:var(--surface);border:1px solid var(--rule);border-radius:6px}
.dcard>*{margin:0}
.dcard__title{font-size:1.125rem}
.dcard__title a{color:inherit}
.dcard__dur{display:flex;flex-wrap:wrap;align-items:baseline;gap:.125rem .5rem}
.dcard__billed{font-size:.8125rem;color:var(--muted)}
.dcard__tape{position:relative;height:14px;background:var(--surface-2);border-radius:2px;box-shadow:inset 0 0 0 1px var(--rule)}
.dcard__tape::after{content:"";position:absolute;inset:0;background:repeating-linear-gradient(90deg,var(--muted) 0 1px,transparent 1px calc(100% / var(--n))) 0 0/100% 40% no-repeat;opacity:.55;pointer-events:none}
.dcard__tape span{position:absolute;top:0;bottom:0;left:0;width:max(4px,calc(min(var(--p),var(--c)) * 100%));background:var(--tape);border-radius:2px;box-shadow:inset 0 0 0 1.5px var(--tape-edge)}
.dcard__tape--month::before{content:"";position:absolute;top:0;bottom:0;left:calc(var(--c) * 100%);width:max(0px,calc((var(--p) - var(--c)) * 100%));background:repeating-linear-gradient(135deg,var(--cap) 0 1.5px,transparent 1.5px 6px);box-shadow:inset 0 0 0 1px var(--cap)}
.dcard__scale{position:relative;display:flex;justify-content:space-between;margin-top:-.375rem;font:400 .6875rem/1 var(--mono);color:var(--muted)}
.dcard__capmark{position:absolute;left:calc(var(--c) * 100%);transform:translateX(-50%);color:var(--cap)}
.dcard__cost{display:flex;flex-wrap:wrap;align-items:baseline;gap:.25rem .5rem;margin-top:.125rem}
.dcard__price{font-size:1.5rem;font-weight:700;letter-spacing:-.01em}
.dcard__cap{padding:0 .375rem;border:1px solid var(--cap);border-radius:2px;color:var(--cap);font-size:.75rem;font-weight:650}
.dcard__how{flex-basis:100%;font:400 .8125rem/1.45 var(--mono);color:var(--muted);overflow-wrap:anywhere}
.dcard__note{font-size:.875rem;color:var(--muted)}

/* ---------- Forced colours (Windows contrast themes) ----------
   Background fills are dropped in this mode, so selection and the tape get system colours. */
@media (forced-colors:active){
.plans__radio--hour:checked~.plans__bar .seg__opt--hour,.plans__radio--day:checked~.plans__bar .seg__opt--day,.plans__radio--month:checked~.plans__bar .seg__opt--month{forced-color-adjust:none;background:Highlight;background:SelectedItem;color:HighlightText;color:SelectedItemText}
.tape__strip{forced-color-adjust:none;background:Highlight;box-shadow:none;outline:1.5px solid CanvasText}
.tape__tick{background:Canvas}
.tape__cover{forced-color-adjust:none;background:Canvas;box-shadow:inset 2px 0 0 CanvasText}
.tape__mode.is-best{outline:2px solid Highlight;outline-offset:-1px}
.tape__mode.is-tie{outline:2px dashed CanvasText;outline-offset:-1px}
.tape__best,.pt__code{border-color:CanvasText}
.ladder__rule,.dcard__tape span,.tape__result{outline:1.5px solid CanvasText}
.tape__badge,.dcard__cap{border-color:CanvasText}
}
