@hanzo/design 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30,16 +30,55 @@
30
30
  --golden-9:11.749rem;
31
31
  --golden-split:38.2% 61.8%; /* @kind other */
32
32
 
33
- /* layout rules (DESIGN.md §1.3) */
33
+ /* layout rules (DESIGN.md §1.3)
34
+ MOBILE-FIRST: the values authored here are the PHONE values, and the
35
+ min-width block at the bottom of this file scales them up. A surface that
36
+ uses the raw token therefore gets a layout that already breathes correctly
37
+ at 390px, with no media query of its own. (This is also the value the
38
+ generator captures for tokens.gen.ts — first occurrence wins, and the
39
+ authored default is the small one.) */
34
40
  --container-max:80rem; /* max-w-7xl — grids */
35
41
  --container-prose:48rem; /* max-w-3xl — centered text */
36
42
  --container-wide:72rem; /* max-w-6xl — landing sections */
37
- --gutter:1rem; /* px-4 */
43
+ /* The page gutter also clears a notch. env() is 0px on every device without
44
+ one, so this is exactly `1rem` in the ordinary case and the safe inset when
45
+ there is something to avoid — no per-app work, no landscape clipping.
46
+ Requires `<meta name="viewport" content="…,viewport-fit=cover">` on the
47
+ host page; without it the UA reports 0 and the max() is inert, not wrong. */
48
+ --gutter:max(1rem,var(--safe-left),var(--safe-right));
38
49
  --gutter-sm:1.5rem; /* sm:px-6 */
39
50
  --gutter-lg:2rem; /* lg:px-8 */
40
- --section-y:4rem; /* py-16 content sections */
41
- --section-y-lg:6rem; /* py-24 landing sections */
42
- --hero-y:5rem; /* py-20 */
43
- --hero-y-lg:8rem; /* lg:py-32 */
44
- --header-height:4rem;
51
+ --section-y:2.5rem; /* py-10 on a phone → py-16 at md */
52
+ --section-y-lg:3.5rem; /* py-14 on a phone → py-24 at md */
53
+ --hero-y:3rem; /* py-12 on a phone → py-20 at md */
54
+ --hero-y-lg:4.5rem; /* py-18 on a phone → py-32 at md */
55
+ --header-height:3.5rem; /* 56px is the phone bar; 64px from md */
56
+
57
+ /* ——— touch ——— */
58
+ /* 44px is the floor a pointer-coarse target may render at (Apple HIG 44pt /
59
+ WCAG 2.5.5 AAA / 2.5.8 AA's 24px, taken at the higher bar). base.css spends
60
+ it automatically under `@media (pointer:coarse)`, so a button does not have
61
+ to opt in. It was previously a bare `min-height:44px` literal in
62
+ hanzoai/id's stylesheet — one app knowing something the system did not. */
63
+ --tap-target:44px;
64
+
65
+ /* ——— safe areas ——— */
66
+ /* The notch/home-indicator insets, named once. Anything pinned to a viewport
67
+ edge — a fixed header, a bottom bar, a sheet — adds the matching one. */
68
+ --safe-top:env(safe-area-inset-top,0px);
69
+ --safe-right:env(safe-area-inset-right,0px);
70
+ --safe-bottom:env(safe-area-inset-bottom,0px);
71
+ --safe-left:env(safe-area-inset-left,0px);
72
+ }
73
+
74
+ /* Scale up from the phone. `md` (48rem) is the same breakpoint grid.css
75
+ declares and Tailwind compiles against — one value, not two that agree. */
76
+ @media (min-width:48rem){
77
+ :root{
78
+ --section-y:4rem; /* py-16 — content sections */
79
+ --section-y-lg:6rem; /* py-24 — landing sections */
80
+ --hero-y:5rem; /* py-20 … */
81
+ --hero-y-lg:8rem; /* … lg:py-32 */
82
+ --header-height:4rem;
83
+ }
45
84
  }
@@ -36,6 +36,19 @@
36
36
  --font-size-8xl:var(--text-8xl);
37
37
  --font-size-9xl:var(--text-9xl);
38
38
 
39
+ /* The size a FORM CONTROL renders at — and the ONE step in this scale that is
40
+ not a constant. iOS Safari zooms the viewport whenever a focused input
41
+ computes below 16px, and this scale's base is 14px, so every surface that
42
+ sized a field from --text-sm or --text-base bought the zoom.
43
+
44
+ It has to be a TOKEN rather than a rule because a control's size is almost
45
+ always set inline (every component in components/forms does), and an inline
46
+ style outranks any stylesheet — including a media query. A var() resolves
47
+ per-device inside that inline style, so this is the only construction that
48
+ actually reaches the control. Fields ask for --text-control; nothing else
49
+ should. */
50
+ --text-control:var(--text-sm);
51
+
39
52
  --weight-normal:400;
40
53
  --weight-medium:500;
41
54
  --weight-semibold:600;
@@ -63,3 +76,11 @@
63
76
  --type-code:400 var(--text-sm)/var(--leading-relaxed) var(--font-mono);
64
77
  --type-eyebrow:600 0.625rem/1 var(--font-sans);
65
78
  }
79
+
80
+ /* On touch, a control goes to 16px. Below that iOS Safari zooms the viewport on
81
+ focus and never zooms back out, which is the single most common way a mobile
82
+ form feels broken. pointer:coarse is the real signal — a desktop mouse keeps
83
+ the compact 13px field. */
84
+ @media (pointer:coarse){
85
+ :root{--text-control:1rem}
86
+ }