@govnepal/css 0.1.0 → 0.2.0

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.
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * Civic Calm — @govnepal/css
3
3
  * The framework-agnostic visual layer. Semantic HTML plus .gov-* classes; no JavaScript.
4
- * Built against design-guidelines 0.2.0-dev (7af0babf).
4
+ * Built against design-guidelines 0.2.0-dev (816565b5).
5
5
  *
6
6
  * This stylesheet holds ALL of Civic Calm's visual decisions. @govnepal/ui adds only behavior
7
7
  * (ARIA, keyboard, focus management) on top of these classes — so a plain-HTML site or a CMS
@@ -659,6 +659,194 @@ a:visited,
659
659
  letter-spacing: 0.1em;
660
660
  }
661
661
 
662
+ /* Checkbox and radio (components/checkbox.md, radio.md).
663
+ *
664
+ * Both are the native input with a styled indicator, and both follow the §5.2 colour hierarchy:
665
+ * the checked mark is color.action.primary — if it is interactive, it is blue. The whole row
666
+ * (input + label) is the hit target, 44px minimum, so a mistap on a phone still lands. */
667
+
668
+ .gov-choice {
669
+ display: flex;
670
+ align-items: flex-start;
671
+ gap: var(--gov-space-3);
672
+ min-block-size: var(--gov-target-min-size);
673
+ padding-block: var(--gov-space-2);
674
+ cursor: pointer;
675
+ }
676
+
677
+ /* The native input is kept (not replaced) so it stays fully accessible; it is visually sized to
678
+ * the 24px indicator and its focus ring is drawn by the shared focus rule. */
679
+ .gov-choice__input {
680
+ inline-size: 24px;
681
+ block-size: 24px;
682
+ flex-shrink: 0;
683
+ margin: 0;
684
+ accent-color: var(--gov-color-action-primary-default);
685
+ cursor: pointer;
686
+ }
687
+
688
+ .gov-choice__label {
689
+ /* Line up the label with the indicator, allowing for the taller Devanagari line. */
690
+ padding-block-start: 0.1em;
691
+ }
692
+
693
+ .gov-choice__hint {
694
+ display: block;
695
+ color: var(--gov-color-text-secondary);
696
+ font-size: var(--gov-type-small-font-size);
697
+ line-height: var(--gov-type-small-line-height);
698
+ }
699
+
700
+ /* A group of choices — the fieldset carries the question as its legend (components/checkbox.md,
701
+ * radio.md). Errors mark the group, never one option. */
702
+ .gov-choice-group {
703
+ border: 0;
704
+ padding: 0;
705
+ margin: 0;
706
+ display: flex;
707
+ flex-direction: column;
708
+ gap: var(--gov-space-2);
709
+ }
710
+
711
+ .gov-choice-group__legend {
712
+ padding: 0;
713
+ font-weight: var(--gov-font-weight-medium);
714
+ margin-block-end: var(--gov-space-2);
715
+ }
716
+
717
+ .gov-choice-group--error {
718
+ /* The whole group gets a lead edge so the error attaches to the question, not a single row. */
719
+ border-inline-start: var(--gov-border-width-lg) solid var(--gov-color-status-error-border);
720
+ padding-inline-start: var(--gov-space-4);
721
+ }
722
+
723
+ .gov-choice-group__error {
724
+ display: flex;
725
+ align-items: flex-start;
726
+ gap: var(--gov-space-2);
727
+ color: var(--gov-color-status-error-text);
728
+ font-weight: var(--gov-font-weight-medium);
729
+ }
730
+
731
+ /* Kiosk: options render as large pressable rows (§8.1.4) — a bordered card per choice. */
732
+ [data-density="kiosk-counter"] .gov-choice {
733
+ border: var(--gov-border-width-md) solid var(--gov-color-border-input);
734
+ border-radius: var(--gov-radius-md);
735
+ padding: var(--gov-space-4);
736
+ }
737
+
738
+ /* Select (components/select.md).
739
+ *
740
+ * The native <select> is the baseline on every platform — it inherits the OS picker on mobile,
741
+ * which beats any custom dropdown on a small screen and works with every assistive technology.
742
+ * Styling touches only the closed control; the option list is never restyled. */
743
+
744
+ .gov-select {
745
+ inline-size: 100%;
746
+ min-block-size: var(--gov-target-min-size);
747
+ padding-inline: var(--gov-space-3);
748
+ padding-block: var(--gov-space-3);
749
+ /* Room for the chevron on the trailing side (logical, so it flips for RTL if ever needed). */
750
+ padding-inline-end: var(--gov-space-8);
751
+
752
+ background: var(--gov-color-background-surface);
753
+ color: var(--gov-color-text-primary);
754
+ border: var(--gov-border-width-md) solid var(--gov-color-border-input);
755
+ border-radius: var(--gov-radius-sm);
756
+
757
+ font-size: var(--gov-type-body-font-size);
758
+ cursor: pointer;
759
+
760
+ /* The chevron is a background SVG using currentColor via a data URI — no icon font, no extra
761
+ * request. appearance:none removes the OS chevron so ours sits consistently. */
762
+ appearance: none;
763
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%231F1F1F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
764
+ background-repeat: no-repeat;
765
+ background-position: right var(--gov-space-3) center;
766
+ }
767
+
768
+ /* The chevron colour can't read a token from inside a data URI, so restate it per dark surface. */
769
+ [data-mode="dark"] .gov-select {
770
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23F1F1EF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
771
+ }
772
+
773
+ .gov-select[aria-invalid="true"] {
774
+ border-color: var(--gov-color-status-error-border);
775
+ }
776
+
777
+ .gov-select[disabled] {
778
+ background-color: var(--gov-color-background-secondary);
779
+ color: var(--gov-color-text-disabled);
780
+ cursor: not-allowed;
781
+ }
782
+
783
+ /* The disabled first option ("Select your province") reads as an instruction, not a value. */
784
+ .gov-select option[disabled] {
785
+ color: var(--gov-color-text-placeholder);
786
+ }
787
+
788
+ /* Details (components/details.md) and warning text (components/warning-text.md).
789
+ *
790
+ * Details is native <details>/<summary> — the platform's own disclosure semantics, so a screen
791
+ * reader announces collapsed/expanded for free and Enter/Space just work. The label states what is
792
+ * inside ("Why we ask this"), never a bare "More". */
793
+
794
+ .gov-details {
795
+ border-block-start: var(--gov-border-width-sm) solid var(--gov-color-border-default);
796
+ padding-block: var(--gov-space-2);
797
+ }
798
+
799
+ .gov-details__summary {
800
+ display: flex;
801
+ align-items: center;
802
+ gap: var(--gov-space-2);
803
+ min-block-size: var(--gov-target-min-size);
804
+ cursor: pointer;
805
+ color: var(--gov-color-link-default);
806
+ font-weight: var(--gov-font-weight-medium);
807
+ /* Remove the default triangle; a rotating chevron replaces it. */
808
+ list-style: none;
809
+ }
810
+
811
+ .gov-details__summary::-webkit-details-marker {
812
+ display: none;
813
+ }
814
+
815
+ .gov-details__chevron {
816
+ inline-size: var(--gov-icon-size-md);
817
+ block-size: var(--gov-icon-size-md);
818
+ flex-shrink: 0;
819
+ transition: transform var(--gov-motion-duration-base) var(--gov-motion-easing-standard);
820
+ }
821
+
822
+ .gov-details[open] .gov-details__chevron {
823
+ transform: rotate(90deg);
824
+ }
825
+
826
+ .gov-details__content {
827
+ padding-block-start: var(--gov-space-3);
828
+ padding-inline-start: var(--gov-space-6);
829
+ color: var(--gov-color-text-secondary);
830
+ }
831
+
832
+ /* Warning text — an inline icon + a short sentence, left-aligned with what it warns about. No
833
+ * card, border, or fill: that treatment belongs to alert. The SENTENCE carries the meaning; the
834
+ * icon and colour reinforce it (rules/status-not-color-alone). */
835
+ .gov-warning-text {
836
+ display: flex;
837
+ align-items: flex-start;
838
+ gap: var(--gov-space-2);
839
+ color: var(--gov-color-status-warning-text);
840
+ font-weight: var(--gov-font-weight-medium);
841
+ }
842
+
843
+ .gov-warning-text__icon {
844
+ inline-size: var(--gov-icon-size-sm);
845
+ block-size: var(--gov-icon-size-sm);
846
+ flex-shrink: 0;
847
+ margin-block-start: 0.15em;
848
+ }
849
+
662
850
  /* Error summary (components/error-summary.md).
663
851
  *
664
852
  * Mandatory on every form, on any failed validation (§7.1) — alongside the inline errors, never
@@ -867,6 +1055,140 @@ a:visited,
867
1055
  color: var(--gov-color-status-error-text);
868
1056
  }
869
1057
 
1058
+ /* Phase banner (components/phase-banner.md), stepper (components/stepper.md), and language
1059
+ * switcher (components/language-switcher.md) — the standalone navigation pieces. */
1060
+
1061
+ /* Phase banner: a single-line band directly below the government header, above content. Plain
1062
+ * text, never colour alone. A thin Simrik-free band using a status tint. */
1063
+ .gov-phase-banner {
1064
+ display: flex;
1065
+ flex-wrap: wrap;
1066
+ align-items: baseline;
1067
+ gap: var(--gov-space-2);
1068
+ padding-block: var(--gov-space-2);
1069
+ background: var(--gov-color-status-info-background);
1070
+ border-block-end: var(--gov-border-width-sm) solid var(--gov-color-status-info-border);
1071
+ }
1072
+
1073
+ .gov-phase-banner__tag {
1074
+ font-weight: var(--gov-font-weight-semibold);
1075
+ color: var(--gov-color-status-info-text);
1076
+ text-transform: uppercase;
1077
+ font-size: var(--gov-type-small-font-size);
1078
+ letter-spacing: 0.03em;
1079
+ }
1080
+
1081
+ /* Stepper: an ordered list of named steps — completed / current / upcoming. */
1082
+ .gov-stepper {
1083
+ list-style: none;
1084
+ display: flex;
1085
+ flex-wrap: wrap;
1086
+ gap: var(--gov-space-4);
1087
+ padding: 0;
1088
+ }
1089
+
1090
+ .gov-stepper__step {
1091
+ display: flex;
1092
+ align-items: center;
1093
+ gap: var(--gov-space-2);
1094
+ color: var(--gov-color-text-secondary);
1095
+ }
1096
+
1097
+ .gov-stepper__step--complete {
1098
+ color: var(--gov-color-status-success-text);
1099
+ }
1100
+
1101
+ .gov-stepper__step--current {
1102
+ color: var(--gov-color-text-primary);
1103
+ font-weight: var(--gov-font-weight-semibold);
1104
+ }
1105
+
1106
+ .gov-stepper__marker {
1107
+ inline-size: 28px;
1108
+ block-size: 28px;
1109
+ flex-shrink: 0;
1110
+ display: inline-flex;
1111
+ align-items: center;
1112
+ justify-content: center;
1113
+ border-radius: var(--gov-radius-full);
1114
+ border: var(--gov-border-width-md) solid currentColor;
1115
+ font-size: var(--gov-type-small-font-size);
1116
+ font-weight: var(--gov-font-weight-semibold);
1117
+ }
1118
+
1119
+ .gov-stepper__step--current .gov-stepper__marker {
1120
+ background: var(--gov-color-interactive-selected-indicator);
1121
+ color: var(--gov-color-text-on-action);
1122
+ border-color: var(--gov-color-interactive-selected-indicator);
1123
+ }
1124
+
1125
+ .gov-stepper__link {
1126
+ color: inherit;
1127
+ }
1128
+
1129
+ /* Condensed "Step 2 of 5" for mobile — shown instead of the full rail below the breakpoint. */
1130
+ .gov-stepper__condensed {
1131
+ display: none;
1132
+ font-weight: var(--gov-font-weight-medium);
1133
+ }
1134
+
1135
+ @media (max-width: 767px) {
1136
+ .gov-stepper {
1137
+ display: none;
1138
+ }
1139
+ .gov-stepper__condensed {
1140
+ display: block;
1141
+ }
1142
+ }
1143
+
1144
+ /* Language switcher: a compact text toggle, each language shown by its autonym, current one
1145
+ * distinguished by weight + underline (never colour alone). */
1146
+ .gov-language-switcher {
1147
+ display: flex;
1148
+ align-items: center;
1149
+ gap: var(--gov-space-2);
1150
+ }
1151
+
1152
+ .gov-language-switcher a {
1153
+ min-block-size: var(--gov-target-min-size);
1154
+ display: inline-flex;
1155
+ align-items: center;
1156
+ padding-inline: var(--gov-space-2);
1157
+ text-decoration: none;
1158
+ color: var(--gov-color-link-default);
1159
+ }
1160
+
1161
+ .gov-language-switcher [aria-current="true"] {
1162
+ color: var(--gov-color-text-primary);
1163
+ font-weight: var(--gov-font-weight-semibold);
1164
+ text-decoration: underline;
1165
+ text-underline-offset: 0.2em;
1166
+ }
1167
+
1168
+ .gov-language-switcher__divider {
1169
+ color: var(--gov-color-text-secondary);
1170
+ }
1171
+
1172
+ /* National identity marks — the emblem and flag (identity/emblem, identity/flag).
1173
+ *
1174
+ * Base sizing only. Both are <img> of verified masters; neither is boxed, recoloured, or given a
1175
+ * background plate. The flag in particular has NO rectangular canvas — its double-pennant
1176
+ * silhouette sits directly on the page background (identity/flag), so it never gets a border or
1177
+ * fill here. */
1178
+
1179
+ .gov-emblem {
1180
+ block-size: auto;
1181
+ max-inline-size: 100%;
1182
+ }
1183
+
1184
+ .gov-flag {
1185
+ block-size: auto;
1186
+ max-inline-size: 100%;
1187
+ /* Explicitly no border, background, or box — the constitutional shape must show as-is. */
1188
+ background: none;
1189
+ border: 0;
1190
+ }
1191
+
870
1192
  /* Government header (components/header.md, implementing identity/government-header).
871
1193
  *
872
1194
  * "The most-rendered identity surface in the whole system — every service, every page. It is
@@ -901,32 +1223,17 @@ a:visited,
901
1223
  margin-inline-end: auto;
902
1224
  }
903
1225
 
904
- /* The emblem is loaded from the verified master in design-assets. It is NEVER drawn here — not
905
- * as an inline SVG, not as a font glyph, not as an approximation. Recreating, recolouring, or
906
- * tracing it is prohibited (identity/emblem), and an outdated or redrawn emblem is a legal error,
907
- * not a style choice. The reversed variant is selected for dark surfaces by the behavior layer. */
1226
+ /* The emblem is loaded from the verified master (identity/emblem), never drawn here — not as an
1227
+ * inline SVG, not as a font glyph, not an approximation. Recreating, recolouring, or tracing it is
1228
+ * prohibited; an outdated or redrawn emblem is a legal error, not a style choice. */
908
1229
  .gov-header__emblem {
909
- block-size: 48px;
910
- inline-size: auto;
1230
+ display: inline-flex;
911
1231
  flex-shrink: 0;
912
1232
  }
913
1233
 
914
- /* Dev-only: shown when no emblem asset has been supplied. It is deliberately ugly and says so.
915
- * design-assets/emblems/files/ is currently EMPTY — no verified master exists yet — and the one
916
- * thing this system must not do is invent a stand-in that looks plausible enough to ship. */
917
- .gov-header__emblem-missing {
918
- display: flex;
919
- align-items: center;
920
- justify-content: center;
1234
+ .gov-header__emblem .gov-emblem {
921
1235
  block-size: 48px;
922
- inline-size: 48px;
923
- flex-shrink: 0;
924
- border: var(--gov-border-width-md) dashed var(--gov-color-status-error-border);
925
- color: var(--gov-color-status-error-text);
926
- font-size: var(--gov-type-caption-font-size);
927
- line-height: 1.1;
928
- text-align: center;
929
- font-weight: var(--gov-font-weight-semibold);
1236
+ inline-size: auto;
930
1237
  }
931
1238
 
932
1239
  /* Nepali first, English second — Article 7 makes Nepali in Devanagari the language of official