TOTEM Studio commited on
Commit
d369b66
·
1 Parent(s): 86d1686

stage 4/5/6: gauge gradient arc + sidebar sizing + nav hover states

Browse files

- Gauge: SVG gradient arc violet>cyan>emerald>gold per manual spec
- Gauge: outer ring, inner radar rings, star glow, state classes
- Sidebar: gradient bg per manual (#07122D), flex layout, logo 190px max
- Nav items: 15px font, 14px radius, hover states, proper margin
- Quote card: 150px min-height, 16px radius, auto-bottom push

Files changed (1) hide show
  1. app.py +87 -30
app.py CHANGED
@@ -316,13 +316,26 @@ TOTEM_CSS = """
316
  width: 256px;
317
  flex: 0 0 256px;
318
  min-height: 100%;
319
- border-right: 1px solid rgba(242, 193, 78, 0.22);
320
- background: linear-gradient(180deg, #050d24 0%, #07122d 65%, #091733 100%);
321
- padding: 20px 18px;
322
  display: flex;
323
  flex-direction: column;
324
  }
325
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
  .totem-main {
327
  flex: 1;
328
  min-width: 0;
@@ -422,27 +435,35 @@ TOTEM_CSS = """
422
 
423
  .signal-track {
424
  fill: none;
425
- stroke: rgba(174, 183, 204, 0.28);
426
- stroke-width: 8;
427
  }
428
 
429
  .signal-progress {
430
  fill: none;
431
- stroke: var(--totem-gold);
432
- stroke-width: 8;
433
  stroke-linecap: round;
434
  transform: rotate(-90deg);
435
  transform-origin: 80px 80px;
 
436
  }
437
 
438
- .signal-core-ring {
439
- fill: rgba(7, 18, 45, 0.7);
440
- stroke: rgba(57, 201, 255, 0.55);
441
- stroke-width: 1.5;
 
 
 
 
 
 
442
  }
443
 
444
  .signal-star {
445
  fill: var(--totem-gold);
 
446
  }
447
 
448
  .totem-signal-label {
@@ -751,34 +772,47 @@ TOTEM_CSS = """
751
  }
752
 
753
  .totem-shell .totem-quote-card {
754
- margin-top: auto;
755
- padding: var(--space-5);
756
- border-radius: var(--radius-card);
757
- border: 1px solid rgba(242, 193, 78, 0.28);
758
- background: radial-gradient(circle at 82% 70%, rgba(138, 77, 255, 0.22), transparent 45%),
759
- linear-gradient(180deg, rgba(16, 26, 58, 0.95), rgba(11, 23, 51, 0.96));
 
760
  color: rgba(246, 241, 232, 0.95);
761
  font-family: var(--font-display);
762
- font-size: 20px;
763
- line-height: 1.35;
764
  font-style: italic;
 
 
 
765
  }
766
 
767
  .totem-shell .totem-nav-item {
768
  height: 48px;
769
  display: flex;
770
  align-items: center;
771
- padding: 0 var(--space-4);
772
- border-radius: 12px;
773
  color: rgba(246, 241, 232, 0.88);
774
- margin-bottom: var(--space-2);
775
  border: 1px solid transparent;
776
  font-family: var(--font-ui);
 
 
 
 
 
 
 
 
777
  }
778
 
779
  .totem-shell .totem-nav-item.active {
780
- border-color: rgba(242, 193, 78, 0.45);
781
- background: linear-gradient(90deg, rgba(242, 193, 78, 0.2), rgba(138, 77, 255, 0.2));
 
782
  }
783
 
784
  .totem-shell .totem-muted {
@@ -1292,19 +1326,42 @@ def render_signal_gauge(value: int) -> str:
1292
  circumference = 427.26
1293
  progress = clamped / 100.0
1294
  dash_offset = circumference * (1 - progress)
 
 
 
 
 
 
 
 
 
 
 
1295
  return f"""
1296
- <div class="totem-signal-wrap">
1297
  <svg class="totem-signal" viewBox="0 0 160 160" role="img" aria-label="TOTEM Signal {clamped} percent">
 
 
 
 
 
 
 
 
 
 
 
1298
  <circle class="signal-track" cx="80" cy="80" r="68"></circle>
 
1299
  <circle
1300
  class="signal-progress"
1301
- cx="80"
1302
- cy="80"
1303
- r="68"
1304
  style="stroke-dasharray:{circumference:.2f};stroke-dashoffset:{dash_offset:.2f};"
1305
  ></circle>
1306
- <circle class="signal-core-ring" cx="80" cy="80" r="34"></circle>
1307
- <circle class="signal-core-ring" cx="80" cy="80" r="22"></circle>
 
 
1308
  <path class="signal-star" d="M80 58 L84.7 73.5 L100.9 73.5 L87.8 82.9 L92.6 98.4 L80 89.1 L67.4 98.4 L72.2 82.9 L59.1 73.5 L75.3 73.5 Z"></path>
1309
  </svg>
1310
  <div class="totem-signal-label">TOTEM Signal {clamped}%</div>
 
316
  width: 256px;
317
  flex: 0 0 256px;
318
  min-height: 100%;
319
+ border-right: 1px solid rgba(246, 241, 232, 0.10);
320
+ background: linear-gradient(180deg, #07122D 0%, #081633 50%, #07122D 100%);
321
+ padding: 28px 0 24px 0;
322
  display: flex;
323
  flex-direction: column;
324
  }
325
 
326
+ .totem-shell .totem-brand {
327
+ padding: 0 24px 0 24px;
328
+ margin-bottom: 28px;
329
+ }
330
+
331
+ .totem-shell .totem-brand-img {
332
+ width: 100%;
333
+ max-width: 190px;
334
+ height: auto;
335
+ display: block;
336
+ border-radius: 8px;
337
+ }
338
+
339
  .totem-main {
340
  flex: 1;
341
  min-width: 0;
 
435
 
436
  .signal-track {
437
  fill: none;
438
+ stroke: rgba(246, 241, 232, 0.10);
439
+ stroke-width: 7;
440
  }
441
 
442
  .signal-progress {
443
  fill: none;
444
+ stroke: url(#gaugeGradient);
445
+ stroke-width: 7;
446
  stroke-linecap: round;
447
  transform: rotate(-90deg);
448
  transform-origin: 80px 80px;
449
+ filter: drop-shadow(0 0 6px rgba(138, 77, 255, 0.6));
450
  }
451
 
452
+ .signal-outer-ring {
453
+ fill: none;
454
+ stroke: rgba(242, 193, 78, 0.28);
455
+ stroke-width: 1;
456
+ }
457
+
458
+ .signal-inner-ring {
459
+ fill: none;
460
+ stroke: rgba(57, 201, 255, 0.18);
461
+ stroke-width: 1;
462
  }
463
 
464
  .signal-star {
465
  fill: var(--totem-gold);
466
+ filter: drop-shadow(0 0 8px rgba(242, 193, 78, 0.7));
467
  }
468
 
469
  .totem-signal-label {
 
772
  }
773
 
774
  .totem-shell .totem-quote-card {
775
+ margin: auto 20px 0 20px;
776
+ padding: 20px;
777
+ min-height: 150px;
778
+ border-radius: 16px;
779
+ border: 1px solid rgba(242, 193, 78, 0.35);
780
+ background: radial-gradient(circle at 82% 70%, rgba(138, 77, 255, 0.28), transparent 50%),
781
+ linear-gradient(180deg, rgba(13, 19, 48, 0.97), rgba(8, 14, 38, 0.98));
782
  color: rgba(246, 241, 232, 0.95);
783
  font-family: var(--font-display);
784
+ font-size: 18px;
785
+ line-height: 1.4;
786
  font-style: italic;
787
+ display: flex;
788
+ flex-direction: column;
789
+ justify-content: flex-end;
790
  }
791
 
792
  .totem-shell .totem-nav-item {
793
  height: 48px;
794
  display: flex;
795
  align-items: center;
796
+ padding: 0 20px;
797
+ border-radius: 14px;
798
  color: rgba(246, 241, 232, 0.88);
799
+ margin: 0 20px 4px 20px;
800
  border: 1px solid transparent;
801
  font-family: var(--font-ui);
802
+ font-size: 15px;
803
+ cursor: pointer;
804
+ transition: background 0.15s, border-color 0.15s;
805
+ }
806
+
807
+ .totem-shell .totem-nav-item:hover {
808
+ background: rgba(246, 241, 232, 0.06);
809
+ border-color: rgba(246, 241, 232, 0.12);
810
  }
811
 
812
  .totem-shell .totem-nav-item.active {
813
+ border-color: rgba(242, 193, 78, 0.65);
814
+ background: linear-gradient(90deg, rgba(242, 193, 78, 0.20), rgba(138, 77, 255, 0.20));
815
+ box-shadow: 0 0 24px rgba(242, 193, 78, 0.25);
816
  }
817
 
818
  .totem-shell .totem-muted {
 
1326
  circumference = 427.26
1327
  progress = clamped / 100.0
1328
  dash_offset = circumference * (1 - progress)
1329
+ # Color state based on signal strength per manual spec
1330
+ if clamped < 25:
1331
+ state_class = "gauge-state-low"
1332
+ elif clamped < 50:
1333
+ state_class = "gauge-state-weak"
1334
+ elif clamped < 70:
1335
+ state_class = "gauge-state-developing"
1336
+ elif clamped < 85:
1337
+ state_class = "gauge-state-strong"
1338
+ else:
1339
+ state_class = "gauge-state-excellent"
1340
  return f"""
1341
+ <div class="totem-signal-wrap {state_class}">
1342
  <svg class="totem-signal" viewBox="0 0 160 160" role="img" aria-label="TOTEM Signal {clamped} percent">
1343
+ <defs>
1344
+ <linearGradient id="gaugeGradient" x1="0%" y1="0%" x2="100%" y2="100%">
1345
+ <stop offset="0%" stop-color="#8A4DFF"/>
1346
+ <stop offset="40%" stop-color="#39C9FF"/>
1347
+ <stop offset="75%" stop-color="#22B573"/>
1348
+ <stop offset="100%" stop-color="#F2C14E"/>
1349
+ </linearGradient>
1350
+ </defs>
1351
+ <!-- Outer decorative ring -->
1352
+ <circle class="signal-outer-ring" cx="80" cy="80" r="76"></circle>
1353
+ <!-- Track -->
1354
  <circle class="signal-track" cx="80" cy="80" r="68"></circle>
1355
+ <!-- Progress arc -->
1356
  <circle
1357
  class="signal-progress"
1358
+ cx="80" cy="80" r="68"
 
 
1359
  style="stroke-dasharray:{circumference:.2f};stroke-dashoffset:{dash_offset:.2f};"
1360
  ></circle>
1361
+ <!-- Inner radar rings -->
1362
+ <circle class="signal-inner-ring" cx="80" cy="80" r="52"></circle>
1363
+ <circle class="signal-inner-ring" cx="80" cy="80" r="40"></circle>
1364
+ <!-- Center star compass -->
1365
  <path class="signal-star" d="M80 58 L84.7 73.5 L100.9 73.5 L87.8 82.9 L92.6 98.4 L80 89.1 L67.4 98.4 L72.2 82.9 L59.1 73.5 L75.3 73.5 Z"></path>
1366
  </svg>
1367
  <div class="totem-signal-label">TOTEM Signal {clamped}%</div>