<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="./support.js"></script>
</head>
<body>
<x-dc>
<helmet>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Archivo:wght@500;600;700&family=JetBrains+Mono:wght@300;400;500;600&display=swap" rel="stylesheet">
<style>
body{margin:0;background:radial-gradient(1200px 800px at 50% 20%, #1a1c20 0%, #101114 60%, #0b0c0e 100%)}
a{color:#ffb454;text-decoration:none} a:hover{color:#ffc97e}
@keyframes ping{0%{transform:scale(0.08);opacity:0.55}75%{transform:scale(1);opacity:0}100%{transform:scale(1);opacity:0}}
@keyframes chipring{0%{transform:scale(0.6);opacity:0.9}100%{transform:scale(2.4);opacity:0}}
@keyframes breathe{0%,100%{opacity:1}50%{opacity:0.25}}
@keyframes bob{0%,100%{transform:translate(0px,0px)}30%{transform:translate(1.4px,-1.1px)}65%{transform:translate(-1.2px,0.9px)}}
</style>
</helmet>
<div style="min-height:100vh;display:grid;place-items:center;padding:36px 24px">
<x-import component-from-global-scope="AndroidDevice" from="./android-frame.jsx" dark="{{ true }}" height="{{ 920 }}" hint-size="428px,936px">
<div data-screen-label="Level" style="position:relative;height:100%;display:flex;flex-direction:column;gap:14px;padding:14px 20px 18px;box-sizing:border-box;overflow:hidden;background:radial-gradient(140% 90% at 50% 0%, #121419 0%, #0a0b0d 55%, #060708 100%);font-family:'Archivo',system-ui,sans-serif;color:#e8eaed">
  <div style="position:absolute;left:-120px;bottom:-120px;width:340px;height:340px;border-radius:50%;background:radial-gradient(circle, rgba(255,164,60,0.14) 0%, rgba(255,164,60,0) 70%);pointer-events:none;opacity:{{ glowOpacity }};transition:opacity 0.6s"></div>

  <div style="display:flex;align-items:center;justify-content:space-between">
    <div style="display:flex;flex-direction:column;gap:3px">
      <div style="font-size:14px;font-weight:700;letter-spacing:4px;color:#e8eaed">LEVEL</div>
      <div style="display:flex;align-items:center;gap:6px">
        <div style="width:5px;height:5px;border-radius:50%;background:#7ed9a0;animation:breathe 2.6s ease-in-out infinite"></div>
        <div style="font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:2px;color:#6f767e">LIVE · FUSED</div>
      </div>
    </div>
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#6f767e" stroke-width="1.6" style="cursor:pointer">
      <circle cx="12" cy="12" r="3.2"></circle>
      <path d="M12 2.8v3M12 18.2v3M2.8 12h3M18.2 12h3M5.5 5.5l2.1 2.1M16.4 16.4l2.1 2.1M18.5 5.5l-2.1 2.1M7.6 16.4l-2.1 2.1"></path>
    </svg>
  </div>

  <div style="display:flex;align-items:center;gap:10px;padding:9px 14px;border:1px solid rgba(255,255,255,0.07);border-radius:12px;background:linear-gradient(180deg, rgba(255,255,255,0.025), rgba(255,255,255,0))">
    <div style="position:relative;width:8px;height:8px;flex:none">
      <div style="position:absolute;inset:0;border-radius:50%;background:{{ sonarDotColor }}"></div>
      <sc-if value="{{ sonarOn }}" hint-placeholder-val="{{ true }}">
        <div style="position:absolute;inset:-3px;border-radius:50%;border:1px solid #5fd4c4;animation:chipring 2.2s ease-out infinite"></div>
      </sc-if>
    </div>
    <div style="font-size:10px;font-weight:600;letter-spacing:2.5px;color:{{ sonarLabelColor }}">SONAR</div>
    <div style="font-family:'JetBrains Mono',monospace;font-size:12px;color:{{ sonarValueColor }}">{{ sonarText }}</div>
    <div style="flex:1"></div>
    <sc-if value="{{ sonarOn }}" hint-placeholder-val="{{ true }}">
      <div style="display:flex;align-items:center;gap:3px">
        <div style="width:2px;height:6px;background:#5fd4c4;opacity:0.35;border-radius:1px"></div>
        <div style="width:2px;height:10px;background:#5fd4c4;opacity:0.6;border-radius:1px"></div>
        <div style="width:2px;height:14px;background:#5fd4c4;opacity:0.9;border-radius:1px"></div>
        <div style="width:2px;height:9px;background:#5fd4c4;opacity:0.5;border-radius:1px"></div>
        <div style="width:2px;height:5px;background:#5fd4c4;opacity:0.3;border-radius:1px"></div>
      </div>
    </sc-if>
  </div>

  <div style="position:relative;display:flex;background:#15171b;border:1px solid rgba(255,255,255,0.06);border-radius:999px;padding:3px">
    <div style="position:absolute;top:3px;bottom:3px;width:calc(50% - 3px);left:{{ thumbLeft }};border-radius:999px;background:linear-gradient(180deg,#2a2d33,#1f2126);border:1px solid rgba(255,255,255,0.1);box-shadow:0 2px 8px rgba(0,0,0,0.5);transition:left 0.25s cubic-bezier(0.3,0.9,0.3,1)"></div>
    <button onClick="{{ setSurface }}" style="position:relative;flex:1;padding:9px 0;background:none;border:none;border-radius:999px;font-family:'Archivo',sans-serif;font-size:12px;font-weight:600;letter-spacing:1.5px;color:{{ surfTabColor }};cursor:pointer;transition:color 0.25s">SURFACE</button>
    <button onClick="{{ setEdge }}" style="position:relative;flex:1;padding:9px 0;background:none;border:none;border-radius:999px;font-family:'Archivo',sans-serif;font-size:12px;font-weight:600;letter-spacing:1.5px;color:{{ edgeTabColor }};cursor:pointer;transition:color 0.25s">EDGE</button>
  </div>

  <sc-if value="{{ isSurface }}" hint-placeholder-val="{{ true }}">
    <div data-screen-label="Surface mode" style="flex:1;display:flex;flex-direction:column;align-items:center;justify-content:space-evenly;min-height:0">
      <svg width="308" height="308" viewBox="0 0 360 360" style="flex:none">
        <defs>
          <radialGradient id="dialFace" cx="42%" cy="34%" r="80%">
            <stop offset="0%" stop-color="#1b1e23"></stop>
            <stop offset="60%" stop-color="#111318"></stop>
            <stop offset="100%" stop-color="#0a0b0e"></stop>
          </radialGradient>
          <radialGradient id="bubbleG" cx="38%" cy="30%" r="75%">
            <stop offset="0%" stop-color="#eaffb0"></stop>
            <stop offset="35%" stop-color="#c3e85e"></stop>
            <stop offset="75%" stop-color="#8ab825"></stop>
            <stop offset="100%" stop-color="#5f8510"></stop>
          </radialGradient>
          <radialGradient id="bubbleHalo" cx="50%" cy="50%" r="50%">
            <stop offset="0%" stop-color="#b7e050" stop-opacity="0.35"></stop>
            <stop offset="100%" stop-color="#b7e050" stop-opacity="0"></stop>
          </radialGradient>
        </defs>
        <circle cx="180" cy="180" r="172" fill="url(#dialFace)" stroke="rgba(255,255,255,0.1)" stroke-width="1"></circle>
        <circle cx="180" cy="180" r="164" fill="none" stroke="rgba(255,255,255,0.28)" stroke-width="7" stroke-dasharray="1.4 41.55"></circle>
        <circle cx="180" cy="180" r="164" fill="none" stroke="rgba(255,255,255,0.12)" stroke-width="5" stroke-dasharray="1 13.35"></circle>
        <sc-if value="{{ sonarOn }}" hint-placeholder-val="{{ true }}">
          <g style="transform-origin:180px 180px;animation:ping 4.5s linear infinite">
            <circle cx="180" cy="180" r="150" fill="none" stroke="#5fd4c4" stroke-width="1" opacity="0.5"></circle>
          </g>
          <g style="transform-origin:180px 180px;animation:ping 4.5s linear 2.25s infinite">
            <circle cx="180" cy="180" r="150" fill="none" stroke="#5fd4c4" stroke-width="1" opacity="0.5"></circle>
          </g>
        </sc-if>
        <circle cx="180" cy="180" r="150" fill="none" stroke="rgba(255,255,255,0.08)" stroke-width="1"></circle>
        <circle cx="180" cy="180" r="100" fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="1"></circle>
        <circle cx="180" cy="180" r="50" fill="none" stroke="rgba(255,255,255,0.14)" stroke-width="1"></circle>
        <text x="186" y="44" font-family="JetBrains Mono" font-size="10" fill="#5a616a">1.5°</text>
        <text x="186" y="94" font-family="JetBrains Mono" font-size="10" fill="#5a616a">1°</text>
        <text x="186" y="144" font-family="JetBrains Mono" font-size="10" fill="#5a616a">0.5°</text>
        <path d="M180 30 V150 M180 210 V330 M30 180 H150 M210 180 H330" stroke="rgba(255,255,255,0.16)" stroke-width="1"></path>
        <path d="M78 249 A122 122 0 0 1 60.5 202" fill="none" stroke="#ffb454" stroke-width="2.5" stroke-linecap="round" opacity="{{ dirOpacity }}" style="transition:opacity 0.5s"></path>
        <g opacity="{{ dirOpacity }}" style="transition:opacity 0.5s">
          <path d="M96 262 l-9 5 3-10" fill="none" stroke="#ffb454" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
        </g>
        <circle cx="180" cy="180" r="2.5" fill="#ffb454"></circle>
        <g transform="translate({{ bubbleX }} {{ bubbleY }})" style="transition:transform 0.7s cubic-bezier(0.3,0.9,0.35,1)">
          <g style="animation:bob 5.5s ease-in-out infinite">
            <circle cx="180" cy="180" r="46" fill="url(#bubbleHalo)"></circle>
            <circle cx="163" cy="196" r="3" fill="#b7e050" opacity="0.12"></circle>
            <circle cx="171" cy="189" r="4.5" fill="#b7e050" opacity="0.22"></circle>
            <circle cx="180" cy="180" r="21" fill="url(#bubbleG)"></circle>
            <circle cx="180" cy="180" r="21" fill="none" stroke="rgba(255,255,255,0.25)" stroke-width="0.8"></circle>
            <ellipse cx="173" cy="172" rx="7" ry="4.5" fill="#ffffff" opacity="0.55" transform="rotate(-32 173 172)"></ellipse>
          </g>
        </g>
      </svg>
      <div style="display:flex;flex-direction:column;align-items:center;gap:4px">
        <div style="font-family:'JetBrains Mono',monospace;font-weight:300;font-size:84px;line-height:1;letter-spacing:-3px;color:#f2f4f6">{{ mainVal }}<span style="font-size:40px;font-weight:400;color:#8a919b;vertical-align:26px;letter-spacing:0">{{ mainUnit }}</span></div>
        <svg width="240" height="22" viewBox="0 0 240 22">
          <line x1="10" y1="14" x2="230" y2="14" stroke="rgba(255,255,255,0.1)" stroke-width="4" stroke-dasharray="1 10"></line>
          <line x1="120" y1="6" x2="120" y2="20" stroke="rgba(255,255,255,0.3)" stroke-width="1.5"></line>
          <rect x="{{ devX }}" y="4" width="3" height="16" rx="1.5" fill="{{ stateColor }}" style="transition:x 0.7s, fill 0.5s"></rect>
        </svg>
        <div style="display:flex;align-items:center;gap:8px">
          <div style="width:5px;height:5px;border-radius:50%;background:{{ stateColor }};transition:background 0.5s"></div>
          <div style="font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:2px;color:#6f767e">{{ subReadout }}</div>
        </div>
      </div>
    </div>
  </sc-if>

  <sc-if value="{{ isEdge }}" hint-placeholder-val="{{ false }}">
    <div data-screen-label="Edge mode" style="flex:1;display:flex;flex-direction:column;align-items:center;justify-content:space-evenly;min-height:0">
      <svg width="340" height="150" viewBox="0 0 340 150" style="flex:none">
        <defs>
          <linearGradient id="tubeG" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stop-color="#07080a"></stop>
            <stop offset="45%" stop-color="#15181d"></stop>
            <stop offset="100%" stop-color="#0b0c0f"></stop>
          </linearGradient>
        </defs>
        <rect x="8" y="34" width="324" height="62" rx="31" fill="url(#tubeG)" stroke="rgba(255,255,255,0.1)" stroke-width="1"></rect>
        <rect x="10" y="36" width="320" height="14" rx="7" fill="rgba(255,255,255,0.03)"></rect>
        <line x1="146" y1="30" x2="146" y2="100" stroke="rgba(255,255,255,0.35)" stroke-width="1.5"></line>
        <line x1="194" y1="30" x2="194" y2="100" stroke="rgba(255,255,255,0.35)" stroke-width="1.5"></line>
        <g transform="translate({{ edgeBx }} 0)" style="transition:transform 0.7s cubic-bezier(0.3,0.9,0.35,1)">
          <ellipse cx="170" cy="65" rx="24" ry="19" fill="url(#bubbleG2)"></ellipse>
          <ellipse cx="170" cy="65" rx="24" ry="19" fill="none" stroke="rgba(255,255,255,0.25)" stroke-width="0.8"></ellipse>
          <ellipse cx="162" cy="57" rx="8" ry="4" fill="#ffffff" opacity="0.5" transform="rotate(-18 162 57)"></ellipse>
        </g>
        <defs>
          <radialGradient id="bubbleG2" cx="38%" cy="30%" r="75%">
            <stop offset="0%" stop-color="#eaffb0"></stop>
            <stop offset="35%" stop-color="#c3e85e"></stop>
            <stop offset="75%" stop-color="#8ab825"></stop>
            <stop offset="100%" stop-color="#5f8510"></stop>
          </radialGradient>
        </defs>
        <line x1="20" y1="118" x2="320" y2="118" stroke="rgba(255,255,255,0.12)" stroke-width="6" stroke-dasharray="1 14"></line>
        <line x1="170" y1="110" x2="170" y2="126" stroke="rgba(255,255,255,0.3)" stroke-width="1.5"></line>
        <text x="14" y="142" font-family="JetBrains Mono" font-size="10" fill="#5a616a">-2°</text>
        <text x="166" y="142" font-family="JetBrains Mono" font-size="10" fill="#5a616a">0</text>
        <text x="312" y="142" font-family="JetBrains Mono" font-size="10" fill="#5a616a">+2°</text>
      </svg>
      <div style="display:flex;flex-direction:column;align-items:center;gap:6px">
        <div style="font-family:'JetBrains Mono',monospace;font-weight:300;font-size:84px;line-height:1;letter-spacing:-3px;color:#f2f4f6">{{ edgeVal }}<span style="font-size:40px;font-weight:400;color:#8a919b;vertical-align:26px;letter-spacing:0">°</span></div>
        <div style="display:flex;align-items:center;gap:8px">
          <div style="width:5px;height:5px;border-radius:50%;background:{{ stateColor }};transition:background 0.5s"></div>
          <div style="font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:2px;color:#6f767e">{{ edgeSubReadout }}</div>
        </div>
      </div>
    </div>
  </sc-if>

  <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px">
    <div style="background:linear-gradient(180deg,#14161b,#101216);border:1px solid rgba(255,255,255,0.06);border-radius:16px;padding:13px 16px 11px;display:flex;flex-direction:column;gap:6px">
      <div style="font-size:9.5px;font-weight:600;letter-spacing:2.5px;color:#6f767e">PITCH</div>
      <div style="font-family:'JetBrains Mono',monospace;font-size:26px;font-weight:400;color:#e8eaed">{{ pitchText }}</div>
      <svg width="100%" height="20" viewBox="0 0 130 20" preserveAspectRatio="none">
        <line x1="0" y1="10" x2="130" y2="10" stroke="rgba(255,255,255,0.08)" stroke-width="1"></line>
        <g style="transform-origin:65px 10px;transform:rotate({{ pitchRot }}deg);transition:transform 0.7s">
          <line x1="20" y1="10" x2="110" y2="10" stroke="{{ stateColor }}" stroke-width="1.5"></line>
        </g>
        <circle cx="65" cy="10" r="2" fill="{{ stateColor }}"></circle>
      </svg>
    </div>
    <div style="background:linear-gradient(180deg,#14161b,#101216);border:1px solid rgba(255,255,255,0.06);border-radius:16px;padding:13px 16px 11px;display:flex;flex-direction:column;gap:6px">
      <div style="font-size:9.5px;font-weight:600;letter-spacing:2.5px;color:#6f767e">ROLL</div>
      <div style="font-family:'JetBrains Mono',monospace;font-size:26px;font-weight:400;color:#e8eaed">{{ rollText }}</div>
      <svg width="100%" height="20" viewBox="0 0 130 20" preserveAspectRatio="none">
        <line x1="0" y1="10" x2="130" y2="10" stroke="rgba(255,255,255,0.08)" stroke-width="1"></line>
        <g style="transform-origin:65px 10px;transform:rotate({{ rollRot }}deg);transition:transform 0.7s">
          <line x1="20" y1="10" x2="110" y2="10" stroke="{{ stateColor }}" stroke-width="1.5"></line>
        </g>
        <circle cx="65" cy="10" r="2" fill="{{ stateColor }}"></circle>
      </svg>
    </div>
  </div>
</div>
</x-import>
</div>
</x-dc>
<script type="text/x-dc" data-dc-script data-props="{&quot;$preview&quot;:{&quot;width&quot;:520,&quot;height&quot;:1000},&quot;leveled&quot;:{&quot;editor&quot;:&quot;boolean&quot;,&quot;default&quot;:false,&quot;tsType&quot;:&quot;boolean&quot;,&quot;section&quot;:&quot;State&quot;},&quot;sonarOn&quot;:{&quot;editor&quot;:&quot;boolean&quot;,&quot;default&quot;:true,&quot;tsType&quot;:&quot;boolean&quot;,&quot;section&quot;:&quot;Sonar&quot;},&quot;units&quot;:{&quot;editor&quot;:&quot;enum&quot;,&quot;options&quot;:[&quot;degrees&quot;,&quot;mm/m&quot;,&quot;percent&quot;],&quot;default&quot;:&quot;degrees&quot;,&quot;tsType&quot;:&quot;string&quot;,&quot;section&quot;:&quot;Readout&quot;}}">
class Component extends DCLogic {
  state = { mode: 'surface' };
  renderVals() {
    const leveled = this.props.leveled ?? false;
    const sonarOn = this.props.sonarOn ?? true;
    const units = this.props.units ?? 'degrees';
    const mode = this.state.mode;
    const pitch = leveled ? 0 : -0.6, roll = leveled ? 0 : -0.3;
    const stateColor = leveled ? '#7ed9a0' : '#ffb454';
    const fmt = (v) => (v > 0 ? '+' : v < 0 ? '-' : '') + Math.abs(v).toFixed(1) + '\u00b0';
    let mainVal, mainUnit;
    if (units === 'mm/m') { mainVal = leveled ? '0.0' : '10.5'; mainUnit = ' mm/m'; }
    else if (units === 'percent') { mainVal = leveled ? '0.0' : '1.2'; mainUnit = '%'; }
    else { mainVal = leveled ? '0.0' : '0.7'; mainUnit = '\u00b0'; }
    return {
      isSurface: mode === 'surface', isEdge: mode === 'edge',
      setSurface: () => this.setState({ mode: 'surface' }),
      setEdge: () => this.setState({ mode: 'edge' }),
      thumbLeft: mode === 'surface' ? '3px' : 'calc(50%)',
      surfTabColor: mode === 'surface' ? '#e8eaed' : '#6f767e',
      edgeTabColor: mode === 'edge' ? '#e8eaed' : '#6f767e',
      sonarOn,
      sonarDotColor: sonarOn ? '#5fd4c4' : '#3a3f45',
      sonarLabelColor: sonarOn ? '#9ba3ac' : '#4d535a',
      sonarValueColor: sonarOn ? '#5fd4c4' : '#4d535a',
      sonarText: sonarOn ? '0.42 m' : 'OFF',
      glowOpacity: leveled ? 0 : 1,
      dirOpacity: leveled ? 0 : 0.9,
      bubbleX: roll * 100, bubbleY: -pitch * 100,
      devX: 118.5 + pitch * 60,
      stateColor,
      mainVal, mainUnit,
      subReadout: leveled ? 'LEVEL \u00b7 HOLD' : '10.5 MM/M \u00b7 HIGH \u2199',
      edgeVal: leveled ? '0.0' : '0.3',
      edgeSubReadout: leveled ? 'LEVEL \u00b7 HOLD' : '5.2 MM/M \u00b7 HIGH LEFT',
      edgeBx: roll * 120,
      pitchText: fmt(pitch), rollText: fmt(roll),
      pitchRot: pitch * 12, rollRot: roll * 12,
    };
  }
}
</script>
</body>
</html>
