<script lang="ts">
  import { createEventDispatcher } from "svelte";
  import type {
    ConnectionState,
    HudConfigLink,
    HudNoticeTone,
    LocaleCode,
    WindowControlAction
  } from "$lib/types/hud";

  export let appName = "";
  export let suiteName = "";
  export let controlAreaLabel = "";
  export let locale: LocaleCode = "zh-CN";
  export let connectionState: ConnectionState = "offline";
  export let connectionLabel = "";
  export let connectedLabel = "";
  export let connectingLabel = "";
  export let disconnectedLabel = "";
  export let deviceLabel = "";
  export let deviceValue = "";
  export let sampleRateLabel = "";
  export let sampleRateValue = "";
  export let channelsLabel = "";
  export let channelsValue = "";
  export let serialPortLabel = "";
  export let serialPortValue = "";
  export let serialPortOptions: string[] = [];
  export let refreshPortsLabel = "";
  export let configLinksLabel = "";
  export let configLinks: HudConfigLink[] = [];
  export let connectActionLabel = "";
  export let disconnectActionLabel = "";
  export let exportActionLabel = "";
  export let exportingActionLabel = "";
  export let importActionLabel = "";
  export let connectionNotice = "";
  export let connectionNoticeTone: HudNoticeTone = "info";
  export let isRefreshingPorts = false;
  export let isConnectDisabled = false;
  export let isExporting = false;
  export let isExportDisabled = false;
  export let isWindowMaximized = false;

  const dispatch = createEventDispatcher<{
    windowcontrol: WindowControlAction;
    localechange: LocaleCode;
    configlink: string;
    portchange: string;
    serialrefresh: void;
    serialconnect: string;
    serialexport: void;
    csvimport: void;
    noticeclear: void;
  }>();

  const connectionToneByState: Record<ConnectionState, "ok" | "warn" | "idle"> = {
    online: "ok",
    connecting: "warn",
    offline: "idle"
  };

  $: connectionTone = connectionToneByState[connectionState];
  $: connectionText =
    connectionState === "online"
      ? connectedLabel
      : connectionState === "connecting"
        ? connectingLabel
        : disconnectedLabel;
  $: connectButtonText =
    connectionState === "online"
      ? disconnectActionLabel
      : connectionState === "connecting"
        ? connectingLabel
        : connectActionLabel;
  $: exportButtonText = isExporting ? exportingActionLabel || exportActionLabel : exportActionLabel;
  $: resolvedSerialPortOptions =
    serialPortOptions.length > 0 ? serialPortOptions : serialPortValue ? [serialPortValue] : [];

  function emitWindowControl(action: WindowControlAction): void {
    dispatch("windowcontrol", action);
  }

  function switchLocale(nextLocale: LocaleCode): void {
    dispatch("localechange", nextLocale);
  }

  function emitConfigLink(linkId: string): void {
    dispatch("configlink", linkId);
  }

  function emitPortChange(event: Event): void {
    const target = event.currentTarget as HTMLSelectElement;
    dispatch("portchange", target.value);
  }

  function emitSerialConnect(): void {
    dispatch("serialconnect", serialPortValue);
  }

  function emitSerialRefresh(): void {
    dispatch("serialrefresh");
  }

  function emitSerialExport(): void {
    dispatch("serialexport");
  }

  function emitCsvImport(): void {
    dispatch("csvimport");
  }

  function emitNoticeClear(): void {
    dispatch("noticeclear");
  }
</script>

<section class="hud-panel" aria-label={controlAreaLabel}>
  <div class="title-bar" role="group" aria-label="Title Bar" data-tauri-drag-region>
    <div class="title-cluster" data-tauri-drag-region>
      <span class="title-pulse" aria-hidden="true"></span>
      <strong class="app-name">{appName}</strong>
      <span class="suite-tag">{suiteName}</span>
    </div>

    <div class="window-controls" aria-label="Window Controls">
      <button
        type="button"
        class="window-btn"
        on:click={() => emitWindowControl("minimize")}
        aria-label="Minimize window"
      >
        <svg viewBox="0 0 12 12" aria-hidden="true">
          <path d="M2 6h8"></path>
        </svg>
      </button>
      <button
        type="button"
        class="window-btn"
        class:is-maximized={isWindowMaximized}
        on:click={() => emitWindowControl("toggle-maximize")}
        aria-label="Toggle maximize window"
      >
        <svg viewBox="0 0 12 12" aria-hidden="true">
          <path d="M2.6 2.6h6.8v6.8h-6.8z"></path>
        </svg>
      </button>
      <button
        type="button"
        class="window-btn is-close"
        on:click={() => emitWindowControl("close")}
        aria-label="Close window"
      >
        <svg viewBox="0 0 12 12" aria-hidden="true">
          <path d="M2.6 2.6l6.8 6.8"></path>
          <path d="M9.4 2.6l-6.8 6.8"></path>
        </svg>
      </button>
    </div>
  </div>

  <div class="control-bar">
    <div class="control-main-row">
      <section class="config-links" aria-label={configLinksLabel}>
        {#each configLinks as link (link.id)}
          <button
            type="button"
            class="config-link tone-{link.tone ?? 'neutral'}"
            class:is-active={Boolean(link.active)}
            on:click={() => emitConfigLink(link.id)}
          >
            <span class="config-indicator" aria-hidden="true"></span>
            <span class="config-label">{link.label}</span>
          </button>
        {/each}
      </section>

      <section class="state-card" aria-label={connectionLabel}>
        <span class="state-dot" class:ok={connectionTone === "ok"} class:warn={connectionTone === "warn"}></span>
        <span class="state-label">{connectionLabel}</span>
        <strong class="state-value">{connectionText}</strong>
      </section>

      <label class="serial-select" aria-label={serialPortLabel}>
        <span class="serial-tag">{serialPortLabel}</span>
        <span class="serial-select-wrap">
          <select
            class="serial-select-input"
            value={serialPortValue}
            disabled={connectionState !== "offline" || isRefreshingPorts}
            on:change={emitPortChange}
          >
            {#each resolvedSerialPortOptions as option}
              <option value={option}>{option}</option>
            {/each}
          </select>
          <span class="serial-select-caret" aria-hidden="true"></span>
        </span>
      </label>

      <button
        type="button"
        class="refresh-btn"
        disabled={isRefreshingPorts || connectionState !== "offline"}
        on:click={emitSerialRefresh}
      >
        <svg viewBox="0 0 16 16" aria-hidden="true">
          <path d="M13 4.8V1.8"></path>
          <path d="M13 1.8H10"></path>
          <path d="M13 1.8a5.7 5.7 0 0 0-9.7 3.4"></path>
          <path d="M3 11.2v3"></path>
          <path d="M3 14.2h3"></path>
          <path d="M3 14.2a5.7 5.7 0 0 0 9.7-3.4"></path>
        </svg>
        <span>{isRefreshingPorts ? `${refreshPortsLabel}...` : refreshPortsLabel}</span>
      </button>

      <button
        type="button"
        class="connect-btn"
        class:is-busy={connectionState === "connecting"}
        class:is-connected={connectionState === "online"}
        disabled={isConnectDisabled}
        on:click={emitSerialConnect}
      >
        <span class="connect-btn-indicator" aria-hidden="true"></span>
        <span>{connectButtonText}</span>
      </button>

      <button
        type="button"
        class="export-btn"
        disabled={isExportDisabled || isExporting}
        on:click={emitSerialExport}
      >
        <svg viewBox="0 0 16 16" aria-hidden="true">
          <path d="M8 2.2v7.2"></path>
          <path d="M5.4 7.8L8 10.5l2.6-2.7"></path>
          <path d="M3.1 12.3h9.8"></path>
        </svg>
        <span>{exportButtonText}</span>
      </button>

      <button type="button" class="import-btn" on:click={emitCsvImport}>
        <svg viewBox="0 0 16 16" aria-hidden="true">
          <path d="M8 10.8V3.6"></path>
          <path d="M5.4 6.3L8 3.6l2.6 2.7"></path>
          <path d="M3.1 12.6h9.8"></path>
        </svg>
        <span>{importActionLabel}</span>
      </button>

      <section class="locale-switch" aria-label="Language">
        <button
          type="button"
          class="locale-btn"
          class:is-active={locale === "zh-CN"}
          on:click={() => switchLocale("zh-CN")}
        >
          中文
        </button>
        <button
          type="button"
          class="locale-btn"
          class:is-active={locale === "en-US"}
          on:click={() => switchLocale("en-US")}
        >
          English
        </button>
      </section>
    </div>

    {#if connectionNotice}
      <div class="connection-notice tone-{connectionNoticeTone}" role={connectionNoticeTone === "warn" ? "alert" : "status"}>
        <p class="connection-notice-text">{connectionNotice}</p>
        <button
          type="button"
          class="notice-close-btn"
          aria-label={locale === "zh-CN" ? "关闭提示" : "Dismiss notice"}
          on:click={emitNoticeClear}
        >
          ×
        </button>
      </div>
    {/if}

    <section class="info-grid">
      <article class="info-cell">
        <p class="meta-label">{deviceLabel}</p>
        <p class="meta-value">{deviceValue}</p>
      </article>
      <article class="info-cell">
        <p class="meta-label">{sampleRateLabel}</p>
        <p class="meta-value">{sampleRateValue}</p>
      </article>
      <article class="info-cell">
        <p class="meta-label">{channelsLabel}</p>
        <p class="meta-value">{channelsValue}</p>
      </article>
    </section>
  </div>
</section>

<style>
  .hud-panel {
    display: grid;
    grid-template-rows: auto auto;
    gap: clamp(0.5rem, 1.2vw, 0.85rem);
    --panel-line: rgb(var(--hud-border-rgb) / 0.34);
    --panel-line-soft: rgb(var(--hud-border-rgb) / 0.22);
    --panel-line-strong: rgb(var(--hud-border-strong-rgb) / 0.42);
    --panel-surface: rgb(var(--hud-surface-rgb) / 0.7);
    --panel-surface-strong: rgb(var(--hud-surface-alt-rgb) / 0.84);
    --panel-surface-deep: rgb(var(--hud-surface-deep-rgb) / 0.9);
    --panel-text: rgb(var(--hud-text-main-rgb) / 0.96);
    --panel-text-dim: rgb(var(--hud-text-dim-rgb) / 0.84);
    --panel-glow: rgb(var(--hud-glow-rgb) / 0.12);
    --panel-glow-alt: rgb(var(--hud-glow-alt-rgb) / 0.12);
  }

  .title-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid var(--panel-line-soft);
    padding: 0.05rem 0.1rem 0.55rem 0.1rem;
    background: linear-gradient(180deg, rgb(var(--hud-surface-alt-rgb) / 0.32), transparent);
  }

  .title-cluster {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    min-width: 0;
  }

  .title-pulse {
    inline-size: 0.52rem;
    block-size: 0.52rem;
    border-radius: 50%;
    background: rgb(var(--hud-lime-rgb) / 0.95);
    box-shadow: 0 0 0 2px rgb(var(--hud-lime-rgb) / 0.14);
  }

  .app-name {
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    color: rgb(var(--hud-text-main-rgb) / 0.98);
    text-transform: uppercase;
  }

  .suite-tag {
    font-size: 0.72rem;
    color: var(--hud-text-dim);
    letter-spacing: 0.1em;
    text-transform: uppercase;
  }

  .window-controls {
    display: inline-flex;
    align-items: center;
    gap: 0.38rem;
  }

  .window-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 1.8rem;
    block-size: 1.52rem;
    border: 1px solid var(--panel-line);
    border-radius: 0.34rem;
    color: rgb(var(--hud-cyan-rgb) / 0.92);
    background: rgb(var(--hud-surface-rgb) / 0.82);
    cursor: pointer;
    transition:
      background-color 200ms ease,
      border-color 200ms ease,
      color 200ms ease;
  }

  .window-btn svg {
    inline-size: 0.8rem;
    block-size: 0.8rem;
    stroke: currentColor;
    stroke-width: 1.4;
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  .window-btn:hover {
    border-color: rgb(var(--hud-cyan-rgb) / 0.42);
    background: rgb(var(--hud-surface-alt-rgb) / 0.9);
    color: rgb(var(--hud-text-main-rgb) / 1);
  }

  .window-btn.is-maximized {
    border-color: rgb(var(--hud-lime-rgb) / 0.5);
    color: rgb(var(--hud-lime-rgb) / 0.92);
  }

  .window-btn.is-close:hover {
    border-color: rgb(var(--hud-orange-rgb) / 0.62);
    background: rgb(var(--hud-surface-deep-rgb) / 0.92);
    color: rgb(var(--hud-orange-rgb) / 0.96);
  }

  .control-bar {
    display: grid;
    gap: 0.45rem;
    padding: 0 0.1rem;
    background: linear-gradient(90deg, rgb(var(--hud-glow-rgb) / 0.02), transparent 45%, rgb(var(--hud-glow-alt-rgb) / 0.015));
  }

  .control-main-row {
    display: flex;
    align-items: center;
    gap: 0.58rem;
    flex-wrap: wrap;
  }

  .state-card {
    display: inline-flex;
    align-items: center;
    gap: 0.42rem;
    min-block-size: 2rem;
    border: 1px solid var(--panel-line);
    border-radius: 999px;
    padding: 0.2rem 0.62rem 0.2rem 0.36rem;
    background: var(--panel-surface);
  }

  .state-dot {
    inline-size: 0.55rem;
    block-size: 0.55rem;
    border-radius: 50%;
    background: rgb(var(--hud-text-dim-rgb) / 0.92);
    box-shadow: 0 0 0 2px rgb(var(--hud-text-dim-rgb) / 0.14);
  }

  .state-dot.ok {
    background: var(--hud-lime);
    box-shadow: 0 0 0 2px rgb(var(--hud-lime-rgb) / 0.16);
  }

  .state-dot.warn {
    background: var(--hud-orange);
    box-shadow: 0 0 0 2px rgb(var(--hud-orange-rgb) / 0.16);
  }

  .state-label {
    color: var(--panel-text-dim);
    font-size: 0.66rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    line-height: 1;
  }

  .state-value {
    color: var(--panel-text);
    font-size: 0.92rem;
    letter-spacing: 0.02em;
    font-weight: 600;
    line-height: 1;
  }

  .serial-select {
    display: inline-flex;
    align-items: center;
    gap: 0.38rem;
    min-block-size: 2rem;
    border: 1px solid var(--panel-line);
    border-radius: 999px;
    padding: 0.18rem 0.2rem 0.18rem 0.56rem;
    background: var(--panel-surface);
    min-inline-size: 0;
  }

  .serial-select-wrap {
    position: relative;
    display: inline-block;
    min-inline-size: 0;
  }

  .serial-tag {
    color: var(--panel-text-dim);
    font-size: 0.66rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    line-height: 1;
    white-space: nowrap;
  }

  .serial-select-input {
    appearance: none;
    inline-size: 100%;
    min-inline-size: 7rem;
    border: 1px solid var(--panel-line);
    border-radius: 999px;
    padding: 0.3rem 1.5rem 0.3rem 0.6rem;
    background: rgb(var(--hud-surface-deep-rgb) / 0.84);
    color: rgb(var(--hud-text-main-rgb) / 0.92);
    font-size: 0.84rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    outline: none;
    transition:
      border-color 180ms ease,
      box-shadow 180ms ease;
  }

  .serial-select-input:hover {
    border-color: rgb(var(--hud-cyan-rgb) / 0.36);
  }

  .serial-select-input:focus-visible {
    border-color: rgb(var(--hud-cyan-rgb) / 0.5);
    box-shadow: 0 0 0 2px rgb(var(--hud-cyan-rgb) / 0.14);
  }

  .serial-select-caret {
    position: absolute;
    inset-inline-end: 0.68rem;
    inset-block-start: 50%;
    inline-size: 0.42rem;
    block-size: 0.42rem;
    border-right: 1px solid rgb(var(--hud-text-main-rgb) / 0.82);
    border-bottom: 1px solid rgb(var(--hud-text-main-rgb) / 0.82);
    transform: translateY(-64%) rotate(45deg);
    pointer-events: none;
  }

  .refresh-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.36rem;
    min-block-size: 2rem;
    border: 1px solid var(--panel-line);
    border-radius: 999px;
    padding: 0.24rem 0.64rem;
    background:
      linear-gradient(180deg, rgb(var(--hud-surface-alt-rgb) / 0.92), rgb(var(--hud-surface-rgb) / 0.88)),
      radial-gradient(circle at 50% 0, rgb(var(--hud-glow-rgb) / 0.1), transparent 58%);
    color: rgb(var(--hud-text-main-rgb) / 0.96);
    font-size: 0.74rem;
    letter-spacing: 0.05em;
    cursor: pointer;
    transition:
      border-color 180ms ease,
      background-color 180ms ease,
      color 180ms ease,
      box-shadow 200ms ease,
      opacity 180ms ease;
  }

  .refresh-btn svg {
    inline-size: 0.84rem;
    block-size: 0.84rem;
    stroke: currentColor;
    stroke-width: 1.35;
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  .refresh-btn:hover:not(:disabled) {
    border-color: rgb(var(--hud-cyan-rgb) / 0.44);
    box-shadow:
      inset 0 0 0 1px rgb(var(--hud-border-strong-rgb) / 0.07),
      0 0 10px rgb(var(--hud-glow-rgb) / 0.1);
  }

  .refresh-btn:disabled {
    opacity: 0.72;
    cursor: default;
  }

  .connect-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.42rem;
    min-block-size: 2rem;
    border: 1px solid rgb(var(--hud-lime-rgb) / 0.4);
    border-radius: 999px;
    padding: 0.24rem 0.76rem;
    background:
      linear-gradient(180deg, rgb(var(--hud-surface-alt-rgb) / 0.96), rgb(var(--hud-surface-rgb) / 0.92)),
      radial-gradient(circle at 50% 0, rgb(var(--hud-glow-alt-rgb) / 0.12), transparent 58%);
    color: rgb(var(--hud-text-main-rgb) / 0.98);
    font-size: 0.78rem;
    letter-spacing: 0.05em;
    cursor: pointer;
    transition:
      border-color 180ms ease,
      background-color 180ms ease,
      color 180ms ease,
      box-shadow 200ms ease,
      opacity 180ms ease;
  }

  .connect-btn:hover:not(:disabled) {
    border-color: rgb(var(--hud-lime-rgb) / 0.62);
    box-shadow:
      inset 0 0 0 1px rgb(var(--hud-text-main-rgb) / 0.08),
      0 0 12px rgb(var(--hud-glow-alt-rgb) / 0.14);
  }

  .connect-btn:disabled {
    opacity: 0.72;
    cursor: default;
  }

  .connect-btn.is-busy {
    border-color: rgb(var(--hud-orange-rgb) / 0.48);
    background:
      linear-gradient(180deg, rgb(var(--hud-surface-alt-rgb) / 0.96), rgb(var(--hud-surface-deep-rgb) / 0.92)),
      radial-gradient(circle at 50% 0, rgb(var(--hud-orange-rgb) / 0.12), transparent 58%);
    color: rgb(var(--hud-orange-rgb) / 0.96);
  }

  .connect-btn.is-connected {
    border-color: rgb(var(--hud-cyan-rgb) / 0.46);
    background:
      linear-gradient(180deg, rgb(var(--hud-surface-alt-rgb) / 0.96), rgb(var(--hud-surface-rgb) / 0.92)),
      radial-gradient(circle at 50% 0, rgb(var(--hud-cyan-rgb) / 0.14), transparent 58%);
    color: rgb(var(--hud-text-main-rgb) / 0.98);
  }

  .connect-btn-indicator {
    inline-size: 0.4rem;
    block-size: 0.4rem;
    border-radius: 999px;
    background: var(--hud-lime);
    box-shadow: 0 0 0 2px rgb(133 255 68 / 0.15);
  }

  .connect-btn.is-busy .connect-btn-indicator {
    background: var(--hud-orange);
    box-shadow: 0 0 0 2px rgb(255 91 63 / 0.16);
  }

  .connect-btn.is-connected .connect-btn-indicator {
    background: var(--hud-cyan);
    box-shadow: 0 0 0 2px rgb(62 232 255 / 0.16);
  }

  .export-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.36rem;
    min-block-size: 2rem;
    border: 1px solid rgb(62 232 255 / 0.4);
    border-radius: 999px;
    padding: 0.24rem 0.72rem;
    background:
      linear-gradient(180deg, rgb(10 28 32 / 0.96), rgb(6 15 18 / 0.92)),
      radial-gradient(circle at 50% 0, rgb(62 232 255 / 0.14), transparent 58%);
    color: rgb(227 251 255 / 0.98);
    font-size: 0.74rem;
    letter-spacing: 0.05em;
    cursor: pointer;
    transition:
      border-color 180ms ease,
      background-color 180ms ease,
      color 180ms ease,
      box-shadow 200ms ease,
      opacity 180ms ease;
  }

  .export-btn svg {
    inline-size: 0.84rem;
    block-size: 0.84rem;
    stroke: currentColor;
    stroke-width: 1.35;
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  .export-btn:hover:not(:disabled) {
    border-color: rgb(115 245 255 / 0.62);
    box-shadow:
      inset 0 0 0 1px rgb(231 255 255 / 0.08),
      0 0 12px rgb(62 232 255 / 0.14);
  }

  .export-btn:disabled {
    opacity: 0.72;
    cursor: default;
  }

  .import-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.36rem;
    min-block-size: 2rem;
    border: 1px solid rgb(122 198 255 / 0.36);
    border-radius: 999px;
    padding: 0.24rem 0.72rem;
    background:
      linear-gradient(180deg, rgb(11 22 32 / 0.94), rgb(7 13 20 / 0.9)),
      radial-gradient(circle at 50% 0, rgb(122 198 255 / 0.13), transparent 58%);
    color: rgb(226 243 255 / 0.97);
    font-size: 0.74rem;
    letter-spacing: 0.05em;
    cursor: pointer;
    transition:
      border-color 180ms ease,
      background-color 180ms ease,
      color 180ms ease,
      box-shadow 200ms ease;
  }

  .import-btn svg {
    inline-size: 0.84rem;
    block-size: 0.84rem;
    stroke: currentColor;
    stroke-width: 1.35;
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  .import-btn:hover {
    border-color: rgb(164 220 255 / 0.6);
    box-shadow:
      inset 0 0 0 1px rgb(231 244 255 / 0.08),
      0 0 12px rgb(122 198 255 / 0.14);
  }

  .connection-notice {
    margin: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    border: 1px solid rgb(95 132 158 / 0.32);
    border-radius: 0.5rem;
    padding: 0.38rem 0.45rem 0.38rem 0.7rem;
    background: rgb(8 14 19 / 0.72);
  }

  .connection-notice-text {
    margin: 0;
    flex: 1;
    min-width: 0;
    color: rgb(214 236 248 / 0.96);
    font-size: 0.72rem;
    letter-spacing: 0.03em;
  }

  .connection-notice.tone-warn {
    border-color: rgb(255 91 63 / 0.42);
    background: rgb(28 12 11 / 0.78);
    color: rgb(255 218 208 / 0.96);
  }

  .connection-notice.tone-ok {
    border-color: rgb(133 255 68 / 0.4);
    background: rgb(18 26 16 / 0.76);
    color: rgb(228 255 214 / 0.96);
  }

  .connection-notice.tone-info {
    border-color: rgb(62 232 255 / 0.34);
    background: rgb(8 17 22 / 0.76);
  }

  .notice-close-btn {
    inline-size: 1.36rem;
    block-size: 1.36rem;
    border: 1px solid rgb(116 151 176 / 0.4);
    border-radius: 0.28rem;
    background: rgb(7 12 16 / 0.82);
    color: rgb(194 225 245 / 0.92);
    font-size: 0.92rem;
    line-height: 1;
    cursor: pointer;
    flex-shrink: 0;
    transition:
      border-color 180ms ease,
      color 180ms ease,
      background-color 180ms ease;
  }

  .notice-close-btn:hover {
    border-color: rgb(62 232 255 / 0.5);
    color: rgb(237 250 255 / 0.98);
    background: rgb(9 16 22 / 0.92);
  }

  .connection-notice.tone-warn .notice-close-btn:hover {
    border-color: rgb(255 91 63 / 0.6);
    color: rgb(255 227 220 / 0.98);
    background: rgb(34 13 12 / 0.9);
  }

  .connection-notice.tone-ok .notice-close-btn:hover {
    border-color: rgb(133 255 68 / 0.56);
    color: rgb(236 255 227 / 0.98);
    background: rgb(17 28 14 / 0.9);
  }

  .info-grid {
    display: flex;
    align-items: center;
    gap: 1.05rem;
    flex-wrap: wrap;
    padding-inline: 0.15rem;
  }

  .info-cell {
    min-width: 0;
    display: inline-flex;
    align-items: baseline;
    gap: 0.42rem;
  }

  .meta-label {
    margin: 0;
    font-size: 0.58rem;
    letter-spacing: 0.1em;
    color: rgb(140 163 181 / 0.82);
    text-transform: uppercase;
  }

  .meta-value {
    margin: 0;
    font-size: 0.78rem;
    letter-spacing: 0.03em;
    color: rgb(205 228 245 / 0.92);
  }

  .locale-switch {
    display: inline-flex;
    align-items: center;
    gap: 0.34rem;
    border: 1px solid rgb(95 132 158 / 0.34);
    border-radius: 999px;
    padding: 0.18rem;
    background: rgb(10 16 20 / 0.7);
  }

  .config-links {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    min-block-size: 2rem;
    border: 1px solid rgb(95 132 158 / 0.36);
    border-radius: 999px;
    padding: 0.17rem 0.2rem;
    background: linear-gradient(180deg, rgb(9 15 19 / 0.9), rgb(4 8 12 / 0.86));
    box-shadow: inset 0 0 0 1px rgb(140 184 210 / 0.06);
  }

  .config-link {
    display: inline-flex;
    align-items: center;
    gap: 0.34rem;
    border: 1px solid transparent;
    border-radius: 999px;
    padding: 0.26rem 0.64rem;
    background: transparent;
    color: rgb(164 188 208 / 0.9);
    font-size: 0.81rem;
    letter-spacing: 0.05em;
    cursor: pointer;
    transition:
      color 180ms ease,
      border-color 180ms ease,
      background-color 180ms ease,
      box-shadow 220ms ease;
  }

  .config-indicator {
    inline-size: 0.34rem;
    block-size: 0.34rem;
    border-radius: 999px;
    background: rgb(136 157 174 / 0.88);
    box-shadow: 0 0 0 2px rgb(136 157 174 / 0.16);
    transition:
      background-color 180ms ease,
      box-shadow 200ms ease;
  }

  .config-label {
    line-height: 1;
  }

  .config-link:hover {
    color: #d7edfb;
    border-color: rgb(62 232 255 / 0.26);
  }

  .config-link.is-active {
    color: #f1fdff;
    border-color: rgb(106 150 180 / 0.56);
    background: rgb(18 27 35 / 0.9);
    box-shadow:
      inset 0 0 0 1px rgb(167 218 252 / 0.08),
      0 0 10px rgb(62 232 255 / 0.12);
  }

  .config-link.tone-cyan.is-active {
    border-color: rgb(62 232 255 / 0.48);
  }

  .config-link.tone-lime.is-active {
    border-color: rgb(133 255 68 / 0.52);
  }

  .config-link.tone-orange.is-active {
    border-color: rgb(255 91 63 / 0.52);
  }

  .config-link.tone-cyan.is-active .config-indicator {
    background: var(--hud-cyan);
    box-shadow: 0 0 0 2px rgb(62 232 255 / 0.17);
  }

  .config-link.tone-lime.is-active .config-indicator {
    background: var(--hud-lime);
    box-shadow: 0 0 0 2px rgb(133 255 68 / 0.17);
  }

  .config-link.tone-orange.is-active .config-indicator {
    background: var(--hud-orange);
    box-shadow: 0 0 0 2px rgb(255 91 63 / 0.18);
  }

  .locale-btn {
    border: 1px solid transparent;
    border-radius: 999px;
    padding: 0.26rem 0.6rem;
    background: transparent;
    color: rgb(150 173 189 / 0.9);
    font-size: 0.7rem;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition:
      color 180ms ease,
      border-color 180ms ease,
      background-color 180ms ease;
  }

  .locale-btn:hover {
    color: #d7edfb;
    border-color: rgb(62 232 255 / 0.3);
  }

  .locale-btn.is-active {
    color: #f1fdff;
    border-color: rgb(133 255 68 / 0.48);
    background: rgb(24 31 25 / 0.9);
  }

  @media (max-width: 1080px) {
    .config-links {
      flex-wrap: wrap;
    }
  }

  @media (max-width: 820px) {
    .control-main-row {
      gap: 0.44rem;
    }

    .config-links {
      flex-wrap: wrap;
    }

    .serial-select {
      padding-inline-start: 0.45rem;
    }

    .info-grid {
      gap: 0.84rem;
    }

  }

  @media (max-width: 620px) {
    .suite-tag {
      display: none;
    }

    .control-main-row {
      align-items: stretch;
    }

    .serial-select {
      inline-size: 100%;
      justify-content: space-between;
    }

    .info-grid {
      gap: 0.42rem 0.8rem;
    }

    .info-cell {
      inline-size: 100%;
      justify-content: space-between;
    }

    .window-btn {
      inline-size: 1.75rem;
    }

  }
</style>
