Files
DodoSSH/hosts-v5-design-spec.md
T

8.2 KiB

Hosts v5 design import — spec and decisions

Source: Claude Design project DodoSSH, file Hosts.dc.html (1920x1080 desktop mock). This file holds (a) the agreed decisions, (b) the palette mapping, (c) the raw design HTML at the bottom.

Agreed decisions (user-approved)

  1. Full re-theme: swap the shared palette (src/DodoSSH.Client.Shell/Theme/Palette.axaml) to the new purple/near-black scheme — both heads recolor together. Embed Montserrat + JetBrains Mono + Material Icons font files in the desktop head. Android keeps its default sans (fonts are per-head; only colors are shared by decision); MonoFont gains JetBrains Mono at the front of its fallback list.
  2. Flat sections: the desktop hosts screen becomes one collapsible section per group (nesting flattened into one heading per group in label order, exactly like the phone's SidebarRows), ungrouped hosts under "No group" first. Per-section collapse + Collapse All. Group cards and the breadcrumb trail leave this screen. Group edit/move/delete move to a menu on the section heading. Collapse state is in-memory only (settings.json stays two scalars by decision).
  3. Pinned folders (QUICK ACCESS): full feature. HostSecret.PinnedPaths (ordered strings, per-path three-way merge like TagIds), drawer editor section, pin-count badge on cards, and a chip strip above the terminal for the connected host; clicking a pin opens the SFTP tab with the remote pane at that path (a second authenticated connection, as SFTP always is here).
  4. Last connected: computed from the synced connection log (max(StartedAt) per HostId) on hosts-screen activation and on SessionEnded; relative time ("just now" / "N min ago" / hours/days), restrung on a 1-minute tick while visible, no background re-read.

Deliberate deviations from the mock (do NOT implement the mock literally on these)

  • Relay checkbox copy keeps the honest wording including "(not wired up yet)" — the design copy implies a working relay; the client dial path does not exist yet. Keep the current sentence structure in HostDrawer.axaml:516-535.
  • Status dot stays two states (green = terminal open, grey = not). The design's amber has no truthful meaning; nothing probes hosts.
  • Card click selects (multi-select depends on it), double-click connects, pencil opens the detail pane. The mock's card-as-link-to-terminal is not adopted.
  • Quick connect keeps the auth word (credential/key/password) instead of the mock's SSH/SFTP kind column — every palette connect is SSH, and a constant printed as a reading is refused in this repo.
  • Find box stays (restyled) — it is the only search that crosses group boundaries.
  • "New group…" moves to the foot of the Group ▼ filter flyout (the mock has no group-creation control).
  • The QUICK ACCESS hint sentence ships as what is true: "Pinned folders appear above the terminal for this host." (no "sidebar" claim).

Palette mapping (design rgb → Palette.axaml key)

Key Old New
CanvasColor #0E1220 #05050A (design body rgb(5,5,10))
Chrome #111629 #10111E (window rgb(16,17,30))
Sidebar #0F1426 #0D0D16 (drawer rgb(13,13,22))
Panel #111629 #10111E
Raised #151B31 #101019 (card rgb(16,16,25))
Field #0B0F1D #101019 (inputs rgb(16,16,25))
Chip #16204A #1A1A28 (rgb(26,26,40))
Hover/Active/ChromeHover derive slightly lighter than their surfaces, e.g. Hover #14151E, Active #1E1E2C, ChromeHover #1E1E2C
Border #1A2138 #1E1E2C (rgb(30,30,44))
BorderMid #232B45 #24243A (rgb(36,36,58))
BorderHover #2E3859 #2C2C3E (rgb(44,44,62))
BorderSubtle/BorderFaint keep one step darker than Border, e.g. #17172", use judgment
Text #FFFFFF #FFFFFF
TextDim #B4BCD4 #EDEDF5 (rgb(237,237,245))
TextFaint #7B849F #9C9EB4 (rgb(156,158,180))
TextGhost #5A6280 #7C7F98 (rgb(124,127,152)); the design also uses #6D6F84 and #5D5F74 for deeper steps — add keys only if needed
AccentColor #5B8CFF #5D42DE (rgb(93,66,222))
AccentText #8FA7FF #A78BFA
AccentInk #0E1220 #FFFFFF (text on accent is white in this design)
AccentSoft/AccentWash 0.35/0.06 same opacities over #5D42DE
NEW: AccentGradient LinearGradientBrush 180deg #8D51E7 → #5D42DE
NEW: AccentGlow for BoxShadow use: 0 0 22 0 #8D51E7 at ~35% alpha
Live #3DDC97 #34D399 (rgb(52,211,153) — the design's own green)
Warn #FFB454 #F59E0B (rgb(245,158,11)); WarnText #F5B942
Danger #E86A6A keep

Radii: cards 12, controls 10, small chips 5-6. Field/control height 40. Primary buttons use AccentGradient + glow.

Monogram avatar hue pairs (bg/fg), assigned by stable hash of host label: violet #241C4F/#A78BFA · green #103A2F/#34D399 · amber #423211/#F5B942 · gray #1E1E2C/#9C9EB4.

Raw design HTML (Hosts.dc.html)

The <sc-for>/{{ }} bits are the design tool's templating; style-hover is a hover style. Sample data lives in the script block at the bottom.

<div data-screen-label="Hosts" style="width:1920px;height:1080px;...background:rgb(16,17,30);...">
  <dc-import name="TitleBar" on-search="{{ openQuickConnect }}" hint-size="100%,53px"></dc-import>
  <div style="display:flex;flex-direction:row;flex-grow:1;min-height:0;">
    <dc-import name="NavRail" active="hosts" mode="ssh" hint-size="255px,100%"></dc-import>
    <div style="flex-grow:1;...padding:34px 36px;...">
      <!-- Header row: title + count chip | Group ▼, Tag ▼, + New host -->
      <span style="font-weight:700;font-size:33px;letter-spacing:-0.5px;color:#fff;">Hosts</span>
      <div style="width:34px;height:30px;border-radius:9px;background:rgb(26,26,40);">10</div>
      <!-- Group / Tag: h40, radius 10, inset 1px rgb(44,44,62) border, hover border accent -->
      <!-- + New host: h40, radius 10, AccentGradient, glow, white 13.5 semibold -->

      <!-- Section heading row (margin 32 0 16): "No group · 6" 12.5 medium rgb(124,127,152)
           right side: collapse icon + "Collapse All" / "Collapse" 12 medium rgb(93,95,116) -->

      <!-- Host grid: 3 columns, gap 14 -->
      <!-- Host card: h120, radius 12, bg rgb(16,16,25), inset 1px rgb(30,30,44), hover border accent
        - avatar 32x32 radius 9 at 21,20 with 2-letter mono bold 12.5 monogram
        - name 17 bold white + 9px status dot, at 68,18
        - addr mono 12.5 rgb(109,111,132) + pin badge (h19 radius 5 bg rgb(26,26,40),
          push_pin icon 11 + count 10.5) at 68,39
        - tag chips bottom-left (h21 radius 5 bg rgb(30,30,44), 11 medium rgb(156,158,180))
        - ago text bottom-right 12 rgb(93,95,116) -->
    </div>

    <!-- Drawer (sc-if drawerOpen): w320, bg rgb(13,13,22), border-left rgb(26,26,40), padding 24 22
      - "New host" 20 bold; subtitle "Saving to **DodoTech ▾** vault" 12.5
      - section labels: 10px semibold letter-spacing 1.2 rgb(93,95,116): ADDRESS / GENERAL / CONNECTION / QUICK ACCESS
      - ADDRESS: h42 radius 10 field with accent 1.5px inset border, ">_" prefix, mono value, blinking caret
      - GENERAL: Name field h40; group dropdown ("No group" + expand_more); Add tag field + 40x40 add button; Notes h58
      - CONNECTION: Username field + w78 port field ("22" mono) on one row; auth dropdown
        ("Password (ask each time)" + expand_more); relay checkbox card (radius 12, 18x18 checkbox,
        title 13 semibold + body 11.5 rgb(124,127,152))
      - QUICK ACCESS: per pin: h33 radius 9 row, folder icon + mono path 12.5 + close ✕;
        add row: mono field "/path/to/folder" + 36x36 add button;
        hint 11.5 rgb(93,95,116)
      - footer: Save host (flex-grow, h44, AccentGradient + glow) + Cancel (w92 h44 ghost) -->

    <!-- Quick connect (sc-if quickConnectOpen): full-window scrim rgba(5,5,10,0.6) + blur(3px),
      card w640 radius 14 bg rgb(16,17,30) top-offset 160
      - header row: ">_" accent mono + mono input "deploy@" + caret + "↵ connect · esc close"
      - rows h44 radius 9: status dot 8px, name mono 13, addr mono 11.5, kind right
        (selected row bg rgb(93,66,222), texts white) -->
  </div>
</div>

Sample data (for tone, not to be shipped): hosts like prod-api-01 / deploy@203.0.113.14 / pins 4 / tags production,api / 2 min ago; pinned = /var/www/app, /etc/nginx, /var/log/pm2.