Files
projax/web/templates/graph.tmpl
mAi 522b7489d3 feat(phase 3i mobile): responsive CSS across all projax pages
- viewport meta on layout.tmpl + login.tmpl (iOS won't render legibly without)
- two breakpoints: tablet (≤768px), phone (≤480px)
- chip strips: horizontal-scroll with sticky labels instead of wrapping
- tables → card lists: classify + bulk render as stacked cards on mobile
- forms: single column on phone; min 44px touch targets on buttons
- dashboard: cards already 1-col, polish for narrow widths; grid jumps to
  2 columns at ≥1280px with stale card spanning both
- /graph: SVG scrolls inside .graph-canvas (max-width 100vw, max-height
  75vh, overflow auto); "fit to screen" toggle flips natural vs viewport
- TestLayoutHasViewportMeta verifies every chrome-bearing route ships the
  meta tag
- CLAUDE.md "Out of scope" drops mobile/Otto-PWA exclusion (head approved
  on m/mAi#1861); replaced with native-PWA-install line for Phase 3j
- design.md adds §"Mobile responsiveness" with breakpoint + principle notes
2026-05-15 19:27:07 +02:00

54 lines
2.3 KiB
Cheetah

{{define "content"}}
<h1>Graph <small class="muted">{{.Matched}} / {{.Total}} items</small></h1>
<section class="tagbar" id="graph-filterbar">
<form id="graph-filter" class="search"
hx-get="/graph"
hx-target="main"
hx-select="main"
hx-swap="outerHTML"
hx-trigger="change from:select, change from:input[type=checkbox], keyup changed delay:200ms from:input[name=q]"
hx-push-url="true">
<input type="search" name="q" value="{{.Filter.Q}}" placeholder="search…" autocomplete="off">
<label>tag&nbsp;
<select name="tag" multiple size="3">
{{$sel := .Filter.Tags}}
{{range .AllTags}}<option value="{{.}}" {{if contains $sel .}}selected{{end}}>{{.}}</option>{{end}}
</select>
</label>
<label>mgmt&nbsp;
<select name="mgmt" multiple size="4">
{{$selM := .Filter.Management}}
<option value="mai" {{if contains $selM "mai"}}selected{{end}}>mai</option>
<option value="self" {{if contains $selM "self"}}selected{{end}}>self</option>
<option value="external" {{if contains $selM "external"}}selected{{end}}>external</option>
<option value="unmanaged"{{if contains $selM "unmanaged"}}selected{{end}}>unmanaged</option>
</select>
</label>
<label class="checkbox">
<input type="checkbox" name="isolate" value="1" {{if .Isolate}}checked{{end}}>
isolate (hide non-matches)
</label>
{{if .Filter.Active}}<a class="clear" href="/graph">clear filters</a>{{end}}
<a class="download" href="/graph?download=svg">download SVG</a>
</form>
</section>
<section class="graph-canvas" id="graph-canvas">
<p class="graph-controls muted">
<button type="button" class="fit-screen" onclick="document.getElementById('graph-canvas').classList.toggle('fit')">fit to screen</button>
<small>scroll / pinch to zoom on touch</small>
</p>
{{template "graph-svg" .P}}
</section>
<section class="graph-legend muted">
<span class="legend-key key-mai">mai</span>
<span class="legend-key key-self">self</span>
<span class="legend-key key-external">external</span>
<span class="legend-key key-mixed">mixed</span>
<span class="legend-key key-unmanaged">unmanaged</span>
· status opacity: active 1.0 · done 0.6 · archived 0.3
</section>
{{end}}