51 lines
2.6 KiB
Svelte
51 lines
2.6 KiB
Svelte
<script lang="ts">
|
|
import RangeValueControl from '$lib/components/RangeValueControl.svelte';
|
|
|
|
export type CombatProfile = {
|
|
encounterSeconds: number;
|
|
hitRate: number;
|
|
headshotRate: number;
|
|
firingActivity: number;
|
|
};
|
|
|
|
let {
|
|
profile = $bindable<CombatProfile>(),
|
|
disabled = false
|
|
}: {
|
|
profile: CombatProfile;
|
|
disabled?: boolean;
|
|
} = $props();
|
|
|
|
function update(key: keyof CombatProfile, value: number) {
|
|
profile = { ...profile, [key]: value };
|
|
}
|
|
</script>
|
|
|
|
<section class="combat-assumptions" aria-labelledby="combat-assumptions-title">
|
|
<div class="section-head">
|
|
<div>
|
|
<p class="eyebrow">COMBAT PROFILE</p>
|
|
<h3 id="combat-assumptions-title">Encounter assumptions</h3>
|
|
</div>
|
|
<small>MODELED, NOT LIVE COMBAT</small>
|
|
</div>
|
|
<p class="supporting">These assumptions drive encounter-average calculations. Individual effects can override them when needed.</p>
|
|
<fieldset class="assumption-grid" disabled={disabled}>
|
|
<RangeValueControl label="Encounter duration" min={10} max={300} step={5} value={profile.encounterSeconds} onchange={(value) => update('encounterSeconds', value)} />
|
|
<RangeValueControl label="Hit rate" min={0} max={100} value={profile.hitRate} onchange={(value) => update('hitRate', value)} />
|
|
<RangeValueControl label="Headshot rate" min={0} max={100} value={profile.headshotRate} onchange={(value) => update('headshotRate', value)} />
|
|
<RangeValueControl label="Firing activity" min={0} max={100} value={profile.firingActivity} onchange={(value) => update('firingActivity', value)} />
|
|
</fieldset>
|
|
</section>
|
|
|
|
<style>
|
|
.combat-assumptions{padding:var(--shd-gap-md);border:1px solid var(--shd-border);border-left:2px solid var(--shd-orange);background:var(--shd-surface)}
|
|
.section-head{display:flex;align-items:start;justify-content:space-between;gap:var(--shd-gap-md)}
|
|
.eyebrow{margin:0 0 3px;color:var(--shd-orange);font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:1.3px}
|
|
h3{margin:0;color:var(--shd-text);font-size:var(--shd-type-body);text-transform:uppercase;letter-spacing:.7px}
|
|
.section-head small{padding:4px 6px;border:1px solid var(--shd-border);color:var(--shd-text-muted);font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:.8px;white-space:nowrap}
|
|
.supporting{margin:var(--shd-gap-sm) 0 var(--shd-gap-md);color:var(--shd-text-muted);font-size:var(--shd-type-supporting);line-height:1.45}
|
|
.assumption-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--shd-gap-md);margin:0;padding:0;border:0}.assumption-grid:disabled{opacity:.55}
|
|
@media(max-width:620px){.section-head{display:grid}.section-head small{width:max-content}.assumption-grid{grid-template-columns:1fr}}
|
|
</style>
|