A container registry that uses the AT Protocol for manifest storage and S3 for blob storage. atcr.io
docker container atproto go
80
fork

Configure Feed

Select the types of activity you want to include in your feed.

add theme overrides

+312 -1
+9 -1
cmd/appview/main.go
··· 13 13 14 14 // Register our custom middleware 15 15 _ "atcr.io/pkg/appview/middleware" 16 + 17 + // Register built-in themes 18 + _ "atcr.io/themes/seamark" 16 19 ) 17 20 18 21 var configFile string ··· 79 82 return fmt.Errorf("failed to load config: %w", err) 80 83 } 81 84 82 - server, err := appview.NewAppViewServer(cfg, nil) 85 + branding, err := appview.LookupTheme(cfg.UI.Theme) 86 + if err != nil { 87 + return err 88 + } 89 + 90 + server, err := appview.NewAppViewServer(cfg, branding) 83 91 if err != nil { 84 92 return fmt.Errorf("failed to initialize server: %w", err) 85 93 }
+4
pkg/appview/config.go
··· 65 65 type UIConfig struct { 66 66 // SQLite database path. 67 67 DatabasePath string `yaml:"database_path" comment:"SQLite database for OAuth sessions, stars, pull counts, and device approvals."` 68 + 69 + // Visual theme name (e.g. "seamark"). Empty string uses default atcr.io branding. 70 + Theme string `yaml:"theme" comment:"Visual theme name (e.g. \"seamark\"). Empty uses default atcr.io branding."` 68 71 } 69 72 70 73 // HealthConfig defines health check and cache settings ··· 136 139 137 140 // UI defaults 138 141 v.SetDefault("ui.database_path", "/var/lib/atcr/ui.db") 142 + v.SetDefault("ui.theme", "") 139 143 140 144 // Health defaults 141 145 v.SetDefault("health.cache_ttl", "15m")
+28
pkg/appview/themes.go
··· 1 + package appview 2 + 3 + import "fmt" 4 + 5 + // themeRegistry maps theme names to their BrandingOverrides constructors. 6 + var themeRegistry = make(map[string]func() *BrandingOverrides) 7 + 8 + // RegisterTheme registers a named theme. Call from init() in theme packages. 9 + func RegisterTheme(name string, fn func() *BrandingOverrides) { 10 + if _, exists := themeRegistry[name]; exists { 11 + panic(fmt.Sprintf("theme %q already registered", name)) 12 + } 13 + themeRegistry[name] = fn 14 + } 15 + 16 + // LookupTheme returns BrandingOverrides for a registered theme name. 17 + // Returns nil for empty name (default branding). Returns an error for 18 + // unknown theme names. 19 + func LookupTheme(name string) (*BrandingOverrides, error) { 20 + if name == "" { 21 + return nil, nil 22 + } 23 + fn, ok := themeRegistry[name] 24 + if !ok { 25 + return nil, fmt.Errorf("unknown theme %q", name) 26 + } 27 + return fn(), nil 28 + }
+67
themes/seamark/embed.go
··· 1 + // Package seamark provides the Seamark visual theme for the ATCR AppView. 2 + // Import with a blank identifier to register: _ "atcr.io/themes/seamark" 3 + // Enable with ATCR_UI_THEME=seamark. 4 + package seamark 5 + 6 + import ( 7 + "embed" 8 + "io/fs" 9 + 10 + "atcr.io/pkg/appview" 11 + ) 12 + 13 + //go:embed public 14 + var publicFS embed.FS 15 + 16 + //go:embed theme.css 17 + var themeCSS string 18 + 19 + func init() { 20 + appview.RegisterTheme("seamark", branding) 21 + } 22 + 23 + func branding() *appview.BrandingOverrides { 24 + // Strip the leading "public" directory so the overlay FS matches the 25 + // structure expected by resolvePublicFS (which looks under "public/"). 26 + pubSub, err := fs.Sub(publicFS, "public") 27 + if err != nil { 28 + panic("seamark: bad embed layout: " + err.Error()) 29 + } 30 + 31 + return &appview.BrandingOverrides{ 32 + PublicFS: prefixFS{sub: pubSub}, 33 + ExtraCSS: themeCSS, 34 + } 35 + } 36 + 37 + // prefixFS re-adds the "public/" prefix so the overlay FS works with 38 + // atcr.io's resolvePublicFS which opens paths like "public/favicon.svg". 39 + type prefixFS struct{ sub fs.FS } 40 + 41 + func (p prefixFS) Open(name string) (fs.File, error) { 42 + const prefix = "public/" 43 + if len(name) > len(prefix) && name[:len(prefix)] == prefix { 44 + return p.sub.Open(name[len(prefix):]) 45 + } 46 + // Non-public paths: return not-found so the overlay falls through. 47 + return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist} 48 + } 49 + 50 + func (p prefixFS) ReadDir(name string) ([]fs.DirEntry, error) { 51 + const prefix = "public/" 52 + if name == "public" { 53 + return fs.ReadDir(p.sub, ".") 54 + } 55 + if len(name) > len(prefix) && name[:len(prefix)] == prefix { 56 + return fs.ReadDir(p.sub, name[len(prefix):]) 57 + } 58 + return nil, &fs.PathError{Op: "readdir", Path: name, Err: fs.ErrNotExist} 59 + } 60 + 61 + func (p prefixFS) ReadFile(name string) ([]byte, error) { 62 + const prefix = "public/" 63 + if len(name) > len(prefix) && name[:len(prefix)] == prefix { 64 + return fs.ReadFile(p.sub, name[len(prefix):]) 65 + } 66 + return nil, &fs.PathError{Op: "readfile", Path: name, Err: fs.ErrNotExist} 67 + }
themes/seamark/public/apple-touch-icon.png

This is a binary file and will not be displayed.

themes/seamark/public/favicon-96x96.png

This is a binary file and will not be displayed.

themes/seamark/public/favicon.ico

This is a binary file and will not be displayed.

+51
themes/seamark/public/favicon.svg
··· 1 + <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 + <!-- Created with Inkscape (http://www.inkscape.org/) --> 3 + 4 + <svg 5 + version="1.1" 6 + id="svg1" 7 + width="1090" 8 + height="1090" 9 + viewBox="0 0 1090 1090" 10 + xmlns:xlink="http://www.w3.org/1999/xlink" 11 + xmlns="http://www.w3.org/2000/svg" 12 + xmlns:svg="http://www.w3.org/2000/svg"> 13 + <defs 14 + id="defs1" /> 15 + <g 16 + id="g1"> 17 + <path 18 + id="path23" 19 + style="display:inline;fill:#274b70;fill-opacity:1" 20 + d="M -0.01317212,1090 H 1090 l 0.015,-185.73378 c 0,0 -12.771,11.11089 -20.3496,9.12889 -4.3399,-0.83912 -8.4264,-2.62038 -12.4391,-4.42115 -8.2227,-3.83234 -15.9956,-8.55376 -24.2327,-12.35744 -12.1338,-5.88311 -24.4765,-11.48724 -37.46146,-15.23384 -24.04271,-7.03785 -49.48404,-9.44127 -74.39516,-6.64199 -21.46625,2.40336 -42.12428,9.23019 -62.20106,16.93758 -14.49619,5.55198 -28.78226,11.664 -43.4538,16.75159 -8.35092,2.88186 -519.89836,-4.03589 -535.96117,6.81185 -12.16816,-5.81244 -56.21202,-23.50947 -68.89637,-28.15501 -20.04627,-7.7693 -41.27822,-12.93472 -62.83331,-13.52787 -22.97961,-0.73438 -46.005,3.80583 -67.270783,12.44855 -12.635563,5.02475 -24.794956,11.1329 -37.185172,16.71586 -1.900211,0.8456 -3.989605,1.74968 -5.981072,2.57383 -5.138432,2.143 -10.388702,4.0021 -15.690331,5.69636 -1.152227,0.39204 -2.306258,0.77931 -3.469222,1.13801 -16.8199417,6.89612 -21.52823655,1.93562 -21.52823655,1.93562 z" /> 21 + <path 22 + id="path22" 23 + style="display:inline;fill:#61bbe1;fill-opacity:1" 24 + d="m 1090,926.95153 c -11.2114,26.3292 -50.8297,0.127 -60.3771,-4.59857 -12.4675,-6.04873 -24.8936,-12.37138 -38.17896,-16.46458 -19.03984,-5.98112 -39.16494,-8.4242 -59.08682,-7.39699 -10.29661,0.53472 -20.49911,2.30579 -30.47082,4.89414 -21.54762,5.52277 -41.98308,14.45497 -62.6372,22.55588 -8.62098,3.34518 -17.3029,6.57622 -26.1953,9.13144 -197.59116,111.70745 -346.02714,76.73205 -561.3711,-2.59824 -8.70256,-3.18696 -16.96793,-7.40804 -25.24965,-11.51468 -6.1587,-3.07626 -12.41209,-5.96242 -18.78301,-8.57403 -17.44031,-7.23104 -35.85399,-12.54162 -54.75191,-13.87663 -18.01617,-1.32455 -36.27571,1.03188 -53.3963,6.78028 -15.29882,5.02733 -29.671525,12.37439 -44.264446,19.09326 -5.527211,2.52184 -11.26033,5.02996 -17.057938,7.06927 -13.183102,2.84061 -34.243289,10.71153 -41.53281788,-0.58829 -1.17550402,95.48431 -0.10901225,61.28612 -2.2055e-4,159.80111 391.05404243,0.012 702.29186243,-0.01 1090,0 0.033,-36.1703 0.01,-163.71777 0.01,-163.71777 z" /> 25 + <path 26 + style="display:inline;fill:#218dc2" 27 + d="m -0.00162752,1090 0.0526526,-27.8286 c 0,0 8.40437732,1.7278 15.97151792,2.6512 33.41462,0.4097 67.31305,-18.9114 91.502107,-29.2702 42.58278,-16.7741 85.89024,-1.2978 117.63973,19.0385 47.09881,18.3937 90.87125,13.4381 132.26905,-11.8054 38.02332,-20.184 90.84811,-18.1331 125.2167,7.0418 43.66694,21.0765 94.45211,18.8173 136.0225,-5.3561 36.32638,-21.2688 85.698,-23.0792 121.33,0.7834 47.48382,27.5274 109.39196,24.1962 150.25816,-3.5602 40.37789,-20.5509 86.85688,-16.917 120.05141,5.6917 26.8896,12.678 56.3726,19.6659 83.0381,16.9163 0.01,8.4157 -0.023,25.7079 -0.023,25.7079 z m -0.06958216,-68.3613 0.02118531,-49.38008 C 29.381094,992.44117 85.126119,954.9885 112.62946,944.16913 c 37.52595,-13.38769 69.89895,-3.34366 111.10946,18.56913 21.87489,9.64713 42.18198,19.08184 55.90444,2.48181 4.83367,-5.84728 8.98261,-11.55836 9.64558,-5.60254 0.97166,8.72892 8.86558,25.52919 9.40053,27.45865 15.93711,16.97012 40.00103,19.47452 -13.41377,28.31252 -43.07485,1.5627 -79.23128,-34.82054 -129.36305,-36.75735 -42.32945,-1.92979 -74.486692,21.47215 -111.200168,31.39655 -14.06499,3.0773 -36.4032106,4.6821 -44.78369168,12.2874 z M 1090,966.75059 c 0.6213,2.2125 0.096,53.09981 0.096,53.09981 -37.5217,7.8169 -100.05213,-33.74134 -145.77011,-39.52717 -45.89414,-0.18586 -34.95376,3.05224 -80.71314,21.05997 -22.49136,10.7156 -66.08351,15.3854 -88.28248,7.3603 13.90226,-17.31704 24.01869,-30.93465 24.01869,-30.93465 43.21199,-1.76049 95.4792,-40.10599 140.87288,-39.58947 46.08879,0.091 63.62466,19.34873 94.44276,29.75887 50.7517,18.24454 55.3355,-1.22766 55.3355,-1.22766 z" 28 + id="path19" /> 29 + <path 30 + id="path17" 31 + style="display:inline;fill:#274b70;fill-opacity:1;stroke:#0f1e30;stroke-width:0" 32 + d="m 546.88086,307.24023 c -16.25149,0.22404 -32.29505,8.53489 -41.47839,22.00999 -6.11046,8.80977 -8.84246,19.73569 -8.27158,30.39314 l 0.006,44.10273 c -6.53042,0.0258 -13.06725,-0.085 -19.59316,0.13473 -10.06021,1.0502 -18.72833,9.8651 -19.48853,19.97117 -0.28915,4.67912 -0.0151,9.36983 -0.11467,14.05387 -0.0182,7.57124 0.085,15.14576 0.0642,22.71471 -0.59209,4.96824 -1.52336,9.88991 -2.40421,14.81234 -28.84204,126.17406 -57.68407,252.34811 -86.5261,378.52217 -7.39964,0.01 -14.82289,0.65866 -22.02965,2.38833 -19.0789,4.35412 -36.8719,14.78777 -49.40118,29.89879 -11.50346,13.82858 -18.51543,31.51251 -18.8269,49.55682 -0.17848,6.78628 -0.1065,13.57846 0.062,20.36364 0.7539,14.95505 5.88537,29.62215 14.46849,41.87946 7.14342,10.27248 16.61869,19.01988 27.73317,24.82958 6.57232,3.2652 14.34528,4.1644 21.43142,2.1489 5.37582,-1.4716 10.1551,-4.4325 15.06509,-6.9737 7.64527,-4.1151 15.34626,-8.3856 23.81815,-10.5515 1.50639,-0.4123 3.21632,-0.8292 4.81412,-1.1888 0.83855,-0.1801 1.96113,-0.4271 2.91476,-0.6072 3.86309,-0.7703 7.97186,-1.384 11.97662,-1.8571 6.71548,-0.7586 13.45217,-1.4014 20.20823,-1.6411 2.6321,-0.07 5.43867,0.061 7.94727,0.3242 2.73679,0.2833 5.49754,0.7503 8.10516,1.3374 3.96612,0.8894 7.84568,2.1308 11.64875,3.5591 0.74664,0.2883 1.7671,0.6836 2.61788,1.0185 9.12665,3.7142 17.91846,8.1848 26.95617,12.103 11.80678,5.194 24.08797,9.4496 36.80079,11.7704 10.14335,1.9097 20.48623,2.5615 30.79664,2.4353 6.8993,0.098 13.82287,0.3937 20.69938,-0.3504 13.79531,-1.2981 27.30912,-5.1527 39.8335,-11.0535 11.07992,-5.0151 21.70146,-10.9248 33.21204,-14.9489 3.49458,-1.2178 7.09987,-2.2522 10.63375,-3.0789 2.26759,-0.5319 4.31819,-0.9453 6.61939,-1.3509 8.66695,-1.5203 17.47663,-2.0074 26.26131,-2.2005 2.28766,-0.015 4.75741,0.073 6.92266,0.3024 9.55998,1.0753 18.85868,3.7706 27.86133,7.0918 1.39686,0.527 3.00255,1.141 4.46827,1.7344 3.03372,1.2215 5.99547,2.5027 8.89227,3.8323 5.47093,2.4963 11.0455,5.3158 16.45758,8.1839 2.94418,1.7125 6.18504,2.9322 9.5677,3.3964 6.47607,0.9567 13.20626,-0.529 18.81961,-3.854 4.24605,-2.4485 8.15298,-5.4463 11.90386,-8.5891 13.20276,-11.3051 23.11206,-26.63756 27.15884,-43.6049 1.89016,-7.78677 2.43703,-15.84137 2.20904,-23.8338 0.0533,-8.82633 0.12149,-17.77819 -2.0432,-26.39839 -4.20691,-18.34832 -15.1256,-34.95719 -29.95652,-46.48705 -15.31265,-12.03638 -34.55411,-18.84375 -53.99187,-19.52067 -1.63184,-0.0655 -3.26452,-0.10786 -4.89769,-0.12281 -2.6944,-10.95755 -5.01744,-21.9618 -7.54773,-32.96412 -26.97758,-119.45401 -53.95516,-238.90803 -80.93274,-358.36205 0.37669,-5.97323 0.055,-11.96025 0.15108,-17.93984 -0.0215,-7.33657 0.0878,-14.68165 -0.25963,-22.01062 -1.18679,-8.96759 -8.58959,-16.53035 -17.3563,-18.4236 -3.83894,-0.82157 -7.78811,-0.36734 -11.67929,-0.48047 -3.43828,0.004 -6.87656,0.007 -10.31484,0.0108 0,0 -1.3085,-61.14045 -2.00196,-61.375 -4.31867,-14.335 -15.6879,-26.23893 -29.66529,-31.51063 -6.4577,-2.50081 -13.40358,-3.70563 -20.32494,-3.6007 z" /> 33 + <path 34 + id="path16" 35 + style="display:inline;fill:#f9e008;fill-opacity:1;stroke:#0f1e30;stroke-width:0" 36 + d="m 549.27734,329.25391 c -15.92457,-0.65336 -29.40908,10.71067 -30.11914,25.38281 -0.0103,0.32413 -0.0142,0.6484 -0.0117,0.97266 h -0.01 v 48.70898 h 57.73633 v -48.70898 h -0.0156 c -0.1224,-14.14529 -12.24206,-25.72681 -27.58008,-26.35547 z m -69.09375,96.48828 c -0.13313,0 -0.24023,0.1071 -0.24023,0.24023 v 31.37696 c 0,0.13312 0.1071,0.24023 0.24023,0.24023 h 136.05469 c 0.13313,0 0.24024,-0.10711 0.24024,-0.24023 v -31.37696 c 0,-0.13313 -0.10711,-0.24023 -0.24024,-0.24023 z m -2.62695,52.32617 -85.60547,374.51172 c 0.0242,-0.10566 194.25696,0.18573 291.36524,0.91992 11.45831,-0.002 20.72461,-0.083 20.69531,-0.21289 l -84.7207,-375.15234 c -0.0245,-0.1086 -141.73438,-0.0664 -141.73438,-0.0664 z M 368.41602,875.9375 c -37.49631,0 -67.6836,27.652 -67.6836,62 V 951.5 c 0,34.348 27.84432,52.0317 32.62489,52.5284 3.52213,0.3659 5.1766,-0.9263 7.49788,-2.0723 19.79102,-9.77106 27.51938,-18.73043 77.34759,-21.70852 49.30636,-2.17161 69.18528,34.67532 129.15625,32.40122 55.96201,3.7193 62.98649,-31.31252 131.14335,-32.71329 32.99055,-2.7514 73.77237,20.39069 81.18591,24.27319 1.62665,0.8519 3.7142,0.1598 4.33515,-0.084 2.94408,-1.1543 31.68359,-18.277 31.68359,-52.625 v -13.5625 c 0,-34.348 -30.18729,-62 -67.68359,-62 z" /> 37 + <path 38 + id="rect1" 39 + style="display:inline;fill:#edc506;fill-opacity:1;stroke:#0f1e30;stroke-width:0" 40 + d="m 554.46094,339.76562 c -12.43766,0 -18.57617,9.82407 -18.57617,22.26172 -0.096,6.55599 0.0253,13.48685 0.0625,20.04297 l 0.0625,22.24805 h 40.86328 v -43.96484 c -0.69011,-11.78122 -10.39708,-20.5879 -22.39063,-20.5879 z m 20.28515,86.04493 v 31.77539 h 41.57227 c 0.0682,-0.0241 0.12242,-0.0783 0.14648,-0.14649 v -31.53711 c -0.0123,-0.0349 -0.0327,-0.0665 -0.0586,-0.0918 z m -0.23047,52.25586 65.05469,375.16211 c 0.12066,6.3e-4 0.24079,10e-4 0.36133,0.002 l 60.87305,0.17383 h 0.082 c 1.99029,-0.0323 3.13533,-0.0714 3.125,-0.11719 l -84.7207,-375.15234 h -0.002 l -0.002,-0.002 h -0.0137 c -0.0466,-0.003 -2.85909,-0.003 -3.0918,-0.006 l -39.17773,-0.0605 c -0.82434,-3.1e-4 -1.65212,2.8e-4 -2.48829,0 z m 68.49024,397.87109 c -0.30147,0.0156 -0.6021,0.033 -0.90234,0.0527 24.35837,2.97069 43.10546,23.61842 43.10546,48.80469 v 39.42578 c 0,5.42101 -0.86859,10.63255 -2.4746,15.50196 32.15427,-0.61129 69.85368,20.76837 76.95312,24.48637 1.62665,0.8519 3.71499,0.1598 4.33594,-0.084 2.1791,-0.8544 18.46765,-10.48342 26.79687,-29.34378 0.17803,-0.40966 0.3619,-0.80956 0.53321,-1.22852 0.43216,-1.04394 0.81832,-2.13589 1.19726,-3.23437 0.22188,-0.64262 0.44798,-1.2809 0.65234,-1.94336 0.43016,-1.41189 0.81813,-2.86004 1.14649,-4.35742 0.0453,-0.1957 0.095,-0.38674 0.13867,-0.58399 0.77367,-3.71825 1.21875,-7.69247 1.21875,-11.93359 v -13.5625 c 0,-4.55407 -0.53106,-8.98996 -1.53906,-13.25977 -1.10972,-4.46696 -2.682,-8.74713 -4.66406,-12.78711 -10.7061,-21.26405 -34.152,-35.95312 -61.48047,-35.95312 z" /> 41 + <path 42 + id="rect17" 43 + style="display:inline;fill:#ffffff;stroke:#0f1e30;stroke-width:0" 44 + d="m 497.65234,507.57617 c -4.04177,-0.13328 -6.04125,2.16956 -7.48828,8.49805 L 425.46094,814.3457 c -0.8144,4.23538 -2.2246,10.49817 7.78515,11.6836 7.02508,0.69367 9.37804,-2.5307 10.51368,-9.25782 l 64.72461,-296.60351 c 1.45516,-8.75244 -0.5719,-9.68254 -6.05469,-11.70508 -1.85628,-0.52724 -3.43009,-0.84229 -4.77735,-0.88672 z m 48.67578,385.41211 -186.23437,0.0879 c -25.6219,-0.52968 -37.98443,24.9384 -41.18945,39.86328 -0.14877,9.59973 1.3897,17.02404 8.49804,17.25977 13.00856,-0.13018 8.62447,-17.92766 14.44727,-24.94141 4.94695,-5.95876 9.88516,-10.21097 19.39453,-12.11719 l 184.64258,-1.32617 c 10.15974,-0.0818 13.70554,-3.90915 13.74414,-10.60742 -0.051,-6.20127 -3.42521,-8.26815 -13.30274,-8.21875 z" /> 45 + <path 46 + id="rect24" 47 + style="fill:#f9e008;fill-opacity:1;stroke:#0f1e30;stroke-width:0" 48 + d="m 240.01367,-547.80469 c 0,5.79888 4.66792,10.46875 10.4668,10.46875 h 24.74023 c 5.79888,0 10.46875,-4.66987 10.46875,-10.46875 0,-5.79887 -4.66987,-10.46679 -10.46875,-10.46679 h -24.74023 c -5.79888,0 -10.4668,4.66792 -10.4668,10.46679 z m 33.99414,-81.32031 c -0.0467,2.67523 0.9312,5.3694 2.94531,7.45508 l 17.18555,17.79687 c 4.02824,4.17137 10.62942,4.28605 14.80078,0.25782 4.17137,-4.02824 4.28605,-10.62942 0.25782,-14.80079 l -17.18555,-17.79687 c -4.02824,-4.17136 -10.62942,-4.28605 -14.80078,-0.25781 -2.08568,2.01412 -3.15643,4.67047 -3.20313,7.3457 z m 0.74414,162.32617 c 0.0467,2.67523 1.11745,5.33159 3.20313,7.34571 4.17136,4.02823 10.77254,3.91354 14.80078,-0.25782 l 17.1875,-17.79687 c 4.02824,-4.17136 3.9116,-10.77255 -0.25977,-14.80078 -4.17136,-4.02824 -10.77059,-3.91355 -14.79882,0.25781 l -17.1875,17.79687 c -2.01412,2.08568 -2.99201,4.77985 -2.94532,7.45508 z m 77.31836,-169.35742 c 0,5.79888 4.66988,10.4668 10.46875,10.4668 5.79888,0 10.4668,-4.66792 10.4668,-10.4668 v -24.74023 c 0,-5.79888 -4.66792,-10.4668 -10.4668,-10.4668 -5.79887,0 -10.46875,4.66792 -10.46875,10.4668 z m 1.03516,200.41016 c 0,5.79887 4.66987,10.46679 10.46875,10.46679 5.79887,0 10.4668,-4.66792 10.4668,-10.46679 v -24.74219 c 0,-5.79888 -4.66793,-10.4668 -10.4668,-10.4668 -5.79888,0 -10.46875,4.66792 -10.46875,10.4668 z" 49 + transform="rotate(90)" /> 50 + </g> 51 + </svg>
+43
themes/seamark/public/icons.svg
··· 1 + <svg xmlns="http://www.w3.org/2000/svg" style="display:none"> 2 + <symbol id="alert-circle" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/></symbol> 3 + <symbol id="alert-triangle" viewBox="0 0 24 24"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></symbol> 4 + <symbol id="anchor" viewBox="0 0 24 24"><path d="M12 6v16"/><path d="m19 13 2-1a9 9 0 0 1-18 0l2 1"/><path d="M9 11h6"/><circle cx="12" cy="4" r="2"/></symbol> 5 + <symbol id="arrow-down" viewBox="0 0 24 24"><path d="M12 5v14"/><path d="m19 12-7 7-7-7"/></symbol> 6 + <symbol id="arrow-down-to-line" viewBox="0 0 24 24"><path d="M12 17V3"/><path d="m6 11 6 6 6-6"/><path d="M19 21H5"/></symbol> 7 + <symbol id="arrow-right" viewBox="0 0 24 24"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></symbol> 8 + <symbol id="box" viewBox="0 0 24 24"><path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/></symbol> 9 + <symbol id="check" viewBox="0 0 24 24"><path d="M20 6 9 17l-5-5"/></symbol> 10 + <symbol id="check-circle" viewBox="0 0 24 24"><path d="M21.801 10A10 10 0 1 1 17 3.335"/><path d="m9 11 3 3L22 4"/></symbol> 11 + <symbol id="chevron-down" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></symbol> 12 + <symbol id="chevron-left" viewBox="0 0 24 24"><path d="m15 18-6-6 6-6"/></symbol> 13 + <symbol id="chevron-right" viewBox="0 0 24 24"><path d="m9 18 6-6-6-6"/></symbol> 14 + <symbol id="circle-x" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></symbol> 15 + <symbol id="compass" viewBox="0 0 24 24"><path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"/><circle cx="12" cy="12" r="10"/></symbol> 16 + <symbol id="container" viewBox="0 0 24 24"><path d="M22 7.7c0-.6-.4-1.2-.8-1.5l-6.3-3.9a1.72 1.72 0 0 0-1.7 0l-10.3 6c-.5.2-.9.8-.9 1.4v6.6c0 .5.4 1.2.8 1.5l6.3 3.9a1.72 1.72 0 0 0 1.7 0l10.3-6c.5-.3.9-1 .9-1.5Z"/><path d="M10 21.9V14L2.1 9.1"/><path d="m10 14 11.9-6.9"/><path d="M14 19.8v-8.1"/><path d="M18 17.5V9.4"/></symbol> 17 + <symbol id="copy" viewBox="0 0 24 24"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></symbol> 18 + <symbol id="database" viewBox="0 0 24 24"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5V19A9 3 0 0 0 21 19V5"/><path d="M3 12A9 3 0 0 0 21 12"/></symbol> 19 + <symbol id="download" viewBox="0 0 24 24"><path d="M12 15V3"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/></symbol> 20 + <symbol id="eye" viewBox="0 0 24 24"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/></symbol> 21 + <symbol id="fingerprint" viewBox="0 0 24 24"><path d="M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4"/><path d="M14 13.12c0 2.38 0 6.38-1 8.88"/><path d="M17.29 21.02c.12-.6.43-2.3.5-3.02"/><path d="M2 12a10 10 0 0 1 18-6"/><path d="M2 16h.01"/><path d="M21.8 16c.2-2 .131-5.354 0-6"/><path d="M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2"/><path d="M8.65 22c.21-.66.45-1.32.57-2"/><path d="M9 6.8a6 6 0 0 1 9 5.2v2"/></symbol> 22 + <symbol id="github" viewBox="0 0 24 24"><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"/><path d="M9 18c-4.51 2-5-2-7-2"/></symbol> 23 + <symbol id="hard-drive" viewBox="0 0 24 24"><line x1="22" x2="2" y1="12" y2="12"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/><line x1="6" x2="6.01" y1="16" y2="16"/><line x1="10" x2="10.01" y1="16" y2="16"/></symbol> 24 + <symbol id="info" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></symbol> 25 + <symbol id="loader-2" viewBox="0 0 24 24"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></symbol> 26 + <symbol id="moon" viewBox="0 0 24 24"><path d="M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401"/></symbol> 27 + <symbol id="package" viewBox="0 0 24 24"><path d="M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z"/><path d="M12 22V12"/><polyline points="3.29 7 12 12 20.71 7"/><path d="m7.5 4.27 9 5.15"/></symbol> 28 + <symbol id="plus" viewBox="0 0 24 24"><path d="M5 12h14"/><path d="M12 5v14"/></symbol> 29 + <symbol id="refresh-ccw" viewBox="0 0 24 24"><path d="M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/><path d="M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16"/><path d="M16 16h5v5"/></symbol> 30 + <symbol id="search" viewBox="0 0 24 24"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></symbol> 31 + <symbol id="server" viewBox="0 0 24 24"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"/><rect width="20" height="8" x="2" y="14" rx="2" ry="2"/><line x1="6" x2="6.01" y1="6" y2="6"/><line x1="6" x2="6.01" y1="18" y2="18"/></symbol> 32 + <symbol id="shield-check" viewBox="0 0 24 24"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/></symbol> 33 + <symbol id="ship" viewBox="0 0 24 24"><path d="M12 10.189V14"/><path d="M12 2v3"/><path d="M19 13V7a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2v6"/><path d="M19.38 20A11.6 11.6 0 0 0 21 14l-8.188-3.639a2 2 0 0 0-1.624 0L3 14a11.6 11.6 0 0 0 2.81 7.76"/><path d="M2 21c.6.5 1.2 1 2.5 1 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1s1.2 1 2.5 1c2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1"/></symbol> 34 + <symbol id="star" viewBox="0 0 24 24"><path d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z"/></symbol> 35 + <symbol id="sun" viewBox="0 0 24 24"><circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/></symbol> 36 + <symbol id="sun-moon" viewBox="0 0 24 24"><path d="M12 2v2"/><path d="M14.837 16.385a6 6 0 1 1-7.223-7.222c.624-.147.97.66.715 1.248a4 4 0 0 0 5.26 5.259c.589-.255 1.396.09 1.248.715"/><path d="M16 12a4 4 0 0 0-4-4"/><path d="m19 5-1.256 1.256"/><path d="M20 12h2"/></symbol> 37 + <symbol id="terminal" viewBox="0 0 24 24"><path d="M12 19h8"/><path d="m4 17 6-6-6-6"/></symbol> 38 + <symbol id="trash-2" viewBox="0 0 24 24"><path d="M10 11v6"/><path d="M14 11v6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></symbol> 39 + <symbol id="triangle-alert" viewBox="0 0 24 24"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></symbol> 40 + <symbol id="user" viewBox="0 0 24 24"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></symbol> 41 + <symbol id="x-circle" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></symbol> 42 + <symbol id="helm" viewBox="0 0 24 24"><path d="M12.337 0c-.475 0-.861 1.016-.861 2.269 0 .527.069 1.011.183 1.396a8.514 8.514 0 0 0-3.961 1.22 5.229 5.229 0 0 0-.595-1.093c-.606-.866-1.34-1.436-1.79-1.43a.381.381 0 0 0-.217.066c-.39.273-.123 1.326.596 2.353.267.381.559.705.84.948a8.683 8.683 0 0 0-1.528 1.716h1.734a7.179 7.179 0 0 1 5.381-2.421 7.18 7.18 0 0 1 5.382 2.42h1.733a8.687 8.687 0 0 0-1.32-1.53c.35-.249.735-.643 1.078-1.133.719-1.027.986-2.08.596-2.353a.382.382 0 0 0-.217-.065c-.45-.007-1.184.563-1.79 1.43a4.897 4.897 0 0 0-.676 1.325 8.52 8.52 0 0 0-3.899-1.42c.12-.39.193-.887.193-1.429 0-1.253-.386-2.269-.862-2.269zM1.624 9.443v5.162h1.358v-1.968h1.64v1.968h1.357V9.443H4.62v1.838H2.98V9.443zm5.912 0v5.162h3.21v-1.108H8.893v-.95h1.64v-1.142h-1.64v-.84h1.853V9.443zm4.698 0v5.162h3.218v-1.362h-1.86v-3.8zm4.706 0v5.162h1.364v-2.643l1.357 1.225 1.35-1.232v2.65h1.365V9.443h-.614l-2.1 1.914-2.109-1.914zm-11.82 7.28a8.688 8.688 0 0 0 1.412 1.548 5.206 5.206 0 0 0-.841.948c-.719 1.027-.985 2.08-.596 2.353.39.273 1.289-.338 2.007-1.364a5.23 5.23 0 0 0 .595-1.092 8.514 8.514 0 0 0 3.961 1.219 5.01 5.01 0 0 0-.183 1.396c0 1.253.386 2.269.861 2.269.476 0 .862-1.016.862-2.269 0-.542-.072-1.04-.193-1.43a8.52 8.52 0 0 0 3.9-1.42c.121.4.352.865.675 1.327.719 1.026 1.617 1.637 2.007 1.364.39-.273.123-1.326-.596-2.353-.343-.49-.727-.885-1.077-1.135a8.69 8.69 0 0 0 1.202-1.36h-1.771a7.174 7.174 0 0 1-5.227 2.252 7.174 7.174 0 0 1-5.226-2.252z" fill="currentColor" stroke="none"/></symbol> 43 + </svg>
+33
themes/seamark/public/robots.txt
··· 1 + # Seamark Container Registry - robots.txt 2 + 3 + User-agent: * 4 + 5 + # Allow public pages 6 + Allow: / 7 + Allow: /r/ 8 + Allow: /u/ 9 + Allow: /search 10 + Allow: /install 11 + Allow: /privacy 12 + Allow: /terms 13 + 14 + # Block API endpoints 15 + Disallow: /api/ 16 + Disallow: /v2/ 17 + 18 + # Block auth and session pages 19 + Disallow: /auth/ 20 + Disallow: /login 21 + Disallow: /settings 22 + Disallow: /device/ 23 + 24 + # Block OG image generation endpoints 25 + Disallow: /og/ 26 + 27 + # Block static assets from indexing (optional, saves crawl budget) 28 + Disallow: /js/ 29 + Disallow: /css/ 30 + Disallow: /static/ 31 + 32 + # Sitemap 33 + Sitemap: https://seamark.dev/sitemap.xml
+21
themes/seamark/public/site.webmanifest
··· 1 + { 2 + "name": "Seamark", 3 + "short_name": "Seamark", 4 + "icons": [ 5 + { 6 + "src": "/web-app-manifest-192x192.png", 7 + "sizes": "192x192", 8 + "type": "image/png", 9 + "purpose": "maskable" 10 + }, 11 + { 12 + "src": "/web-app-manifest-512x512.png", 13 + "sizes": "512x512", 14 + "type": "image/png", 15 + "purpose": "maskable" 16 + } 17 + ], 18 + "theme_color": "#274b70", 19 + "background_color": "#274b70", 20 + "display": "standalone" 21 + }
+28
themes/seamark/public/sitemap-static.xml
··· 1 + <?xml version="1.0" encoding="UTF-8"?> 2 + <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 3 + <url> 4 + <loc>https://seamark.dev/</loc> 5 + <changefreq>daily</changefreq> 6 + <priority>1.0</priority> 7 + </url> 8 + <url> 9 + <loc>https://seamark.dev/search</loc> 10 + <changefreq>daily</changefreq> 11 + <priority>0.8</priority> 12 + </url> 13 + <url> 14 + <loc>https://seamark.dev/install</loc> 15 + <changefreq>monthly</changefreq> 16 + <priority>0.9</priority> 17 + </url> 18 + <url> 19 + <loc>https://seamark.dev/privacy</loc> 20 + <changefreq>yearly</changefreq> 21 + <priority>0.3</priority> 22 + </url> 23 + <url> 24 + <loc>https://seamark.dev/terms</loc> 25 + <changefreq>yearly</changefreq> 26 + <priority>0.3</priority> 27 + </url> 28 + </urlset>
+14
themes/seamark/public/sitemap.xml
··· 1 + <?xml version="1.0" encoding="UTF-8"?> 2 + <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 3 + <sitemap> 4 + <loc>https://seamark.dev/sitemap-static.xml</loc> 5 + </sitemap> 6 + <!-- Future: uncomment when dynamic generation is implemented 7 + <sitemap> 8 + <loc>https://seamark.dev/sitemap-users.xml</loc> 9 + </sitemap> 10 + <sitemap> 11 + <loc>https://seamark.dev/sitemap-repos.xml</loc> 12 + </sitemap> 13 + --> 14 + </sitemapindex>
themes/seamark/public/web-app-manifest-192x192.png

This is a binary file and will not be displayed.

themes/seamark/public/web-app-manifest-512x512.png

This is a binary file and will not be displayed.

+14
themes/seamark/theme.css
··· 1 + /* Seamark color overrides (injected after atcr.io's compiled stylesheet) */ 2 + [data-theme="dark"] { 3 + --color-secondary: oklch(90% 0.182 98.111); 4 + --color-secondary-content: oklch(30% 0.182 98.111); 5 + --color-accent: oklch(66.6% 0.121 28); 6 + --color-accent-content: oklch(28% 0.121 28); 7 + } 8 + 9 + [data-theme="light"] { 10 + --color-secondary: oklch(76% 0.095 76.1); 11 + --color-secondary-content: oklch(27.1% 0.026 76.4); 12 + --color-accent: oklch(66.6% 0.121 28); 13 + --color-accent-content: oklch(28% 0.121 28); 14 + }