diff --git a/3dcomunity/3d_comunity_cool.webp b/3dcomunity/3d_comunity_cool.webp new file mode 100644 index 0000000..8e5db29 Binary files /dev/null and b/3dcomunity/3d_comunity_cool.webp differ diff --git a/3dcomunity/3d_comunity_not_cool.webp b/3dcomunity/3d_comunity_not_cool.webp new file mode 100644 index 0000000..8e5db29 Binary files /dev/null and b/3dcomunity/3d_comunity_not_cool.webp differ diff --git a/3dcomunity/index.html b/3dcomunity/index.html index ed76384..720fa01 100644 --- a/3dcomunity/index.html +++ b/3dcomunity/index.html @@ -7,60 +7,67 @@ +
- - - - - - - - - - - - - + + + + + + + + + + + + +
- - + + - - - - - - - - - - - - + + + + + + + + + + + + +
diff --git a/3dcomunity/styles.css b/3dcomunity/styles.css index 935f585..507939f 100644 --- a/3dcomunity/styles.css +++ b/3dcomunity/styles.css @@ -394,6 +394,26 @@ body { box-shadow: 0 0 0 2px rgba(76,175,80,0.4) inset; } +.site-header{ position: relative; } + +.site-logo{ + position: absolute; + left: clamp(10px, 2vw, 18px); + top: clamp(10px, 1.6vw, 14px); + width: 150px; height: 150px; + display: inline-grid; place-items: center; + border-radius: 10px; + border: 1px solid #1a1a1a; + background: #111; + box-shadow: 0 10px 18px rgba(0,0,0,.55); +} +.site-logo img{ width: 100%; height: auto; display: block; } +.site-logo:focus-visible{ outline: 2px solid rgba(57,255,20,.9); outline-offset: 3px; } + +@media (max-width: 680px){ + .site-logo{ width: 0px; height: 0px; } +} + /* ================================= 9) Responsive ================================= */ diff --git a/3dcomunity/sub/3d_comunity_not_cool.webp b/3dcomunity/sub/3d_comunity_not_cool.webp new file mode 100644 index 0000000..8e5db29 Binary files /dev/null and b/3dcomunity/sub/3d_comunity_not_cool.webp differ diff --git a/3dcomunity/sub/about.css b/3dcomunity/sub/about.css new file mode 100644 index 0000000..af29d41 --- /dev/null +++ b/3dcomunity/sub/about.css @@ -0,0 +1,377 @@ +/* =========================== + about.css — 3DCOMMUNITY.NET + Diseño full-width + botones neon + (coloca las fuentes en /fonts) +=========================== */ + +/* 0) Reset + Variables */ +* { margin: 0; padding: 0; box-sizing: border-box; } +html, body { height: 100%; } + +:root{ + /* Colores base */ + --bg-0: #0a0a0a; + --bg-1: #0f0f0f; + --bg-2: #151515; + --panel: #1b1b1b; + --text: #f2f2f2; + --muted: #a9a9a9; + + /* Neón */ + --neon-green: #39FF14; + --neon-orange: #FF7A18; + + /* Gradientes */ + --grad-gn-or: linear-gradient(90deg, var(--neon-green) 0%, var(--neon-orange) 100%); + --grad-or-gn: linear-gradient(90deg, var(--neon-orange) 0%, var(--neon-green) 100%); + + /* Sombras / bordes */ + --shadow: rgba(0,0,0,.6); + --stroke: #0e0e0e; + + /* Tipografías */ + --font-ui: 'Oxanium', 'Rajdhani', 'Inter', system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; + --font-title: 'ThreeDIsometric', var(--font-ui); + --font-display: 'Gunplay', var(--font-ui); + + /* Tamaños */ + --header-h: clamp(88px, 16vh, 160px); + --radius: 16px; + --pad: clamp(14px, 2vw, 24px); +} + +/* 1) Fuentes locales (absolutas para que funcionen en /sub) */ +@font-face{ + font-family: 'ThreeDIsometric'; + src: url('/fonts/3DIsometric-Regular.ttf') format('truetype'), + url('/fonts/3DIsometric-Regular.otf') format('opentype'); + font-weight: 700; + font-style: normal; + font-display: swap; +} +@font-face{ + font-family: 'Gunplay'; + src: url('/fonts/Gunplay-Regular.otf') format('opentype'); + font-weight: 400; + font-style: normal; + font-display: swap; +} +@font-face{ + font-family: 'Oxanium'; + src: url('/fonts/Oxanium-VariableFont_wght.ttf') format('truetype'); + font-weight: 200 800; + font-style: normal; + font-display: swap; +} + +/* 2) Base documento */ +body{ + font-family: var(--font-ui); + color: var(--text); + background: + radial-gradient(1200px 700px at 8% -10%, #141414 0%, #0c0c0c 55%, #070707 100%), + var(--bg-0); + min-height: 100svh; + display: grid; + grid-template-rows: var(--header-h) 1fr; +} +*::-webkit-scrollbar { width: 10px; height: 10px; } +*::-webkit-scrollbar-thumb { background: #2a2a2a; border-radius: 999px; } +*::-webkit-scrollbar-thumb:hover { background: #3a3a3a; } + +@media (prefers-reduced-motion: reduce){ + * { animation: none !important; transition: none !important; } +} + +/* 3) Header + Navegación (coherente con la home) */ +.site-header{ + background: linear-gradient(180deg, #0e0e0e 0%, #0a0a0a 100%); + border-bottom: 1px solid #121212; + box-shadow: 0 6px 24px var(--shadow); + display: grid; + grid-auto-rows: min-content; + align-content: center; + justify-items: center; + gap: .65rem; + padding: clamp(10px, 2vw, 18px) clamp(14px, 2.4vw, 22px) clamp(14px, 2.6vw, 28px); +} +.site-title{ + font-family: var(--font-title); + font-weight: 800; + font-size: clamp(2.6rem, 6.5vw, 5rem); + letter-spacing: .06em; + color: var(--neon-orange); + text-shadow: + 0 0 6px rgba(255,122,24,.25), + 0 12px 28px rgba(0,0,0,.45); + white-space: nowrap; +} +.nav-menu{ + display: flex; flex-wrap: wrap; justify-content: center; + gap: .75rem .85rem; +} + +/* 4) Botones globales (bonitos, con hover y variantes) */ +.btn{ + --h: clamp(44px, 5.4vh, 56px); + --px: clamp(16px, 2.4vw, 26px); + + display: inline-flex; align-items: center; justify-content: center; + height: var(--h); padding: 0 var(--px); + border-radius: 14px; + border: 1px solid #1a1a1a; + font-family: var(--font-display); + font-weight: 800; letter-spacing: .02em; + text-decoration: none; user-select: none; cursor: pointer; + + background-image: var(--grad-gn-or); + background-size: 220% 100%; + background-position: 0% 50%; + color: #0b0b0b; + + box-shadow: + 0 8px 22px rgba(0,0,0,.55), + 0 0 0 0 rgba(57,255,20,0); + transition: background-position .35s ease, transform .12s ease, + box-shadow .25s ease, filter .2s ease, border-color .2s ease, opacity .2s ease; + position: relative; isolation: isolate; +} +.btn::after{ + content:""; position: absolute; inset: -2px; border-radius: inherit; + background: radial-gradient(60% 60% at 50% 50%, rgba(57,255,20,.18), rgba(255,122,24,.1) 60%, transparent 70%); + z-index: -1; opacity: 0; transition: opacity .25s ease; +} +.btn:hover{ + background-position: 100% 50%; + transform: translateY(-1px); + box-shadow: + 0 14px 28px rgba(0,0,0,.65), + 0 0 18px rgba(57,255,20,.28), + 0 0 28px rgba(255,122,24,.22); + filter: saturate(1.07); + border-color: #262626; +} +.btn:hover::after{ opacity: 1; } +.btn:active{ transform: translateY(0); box-shadow: inset 0 4px 10px rgba(0,0,0,.45); } +.btn:focus-visible{ outline: 2px solid rgba(57,255,20,.9); outline-offset: 3px; } + +/* Variantes */ +.btn-green{ background-image: none; background: var(--neon-green); } +.btn-orange{ background-image: none; background: var(--neon-orange); } +.btn-outline{ + background: transparent; + color: var(--text); + border-color: #2d2d2d; + box-shadow: 0 8px 22px rgba(0,0,0,.45); +} +.btn-outline:hover{ + background: #151515; + border-color: var(--neon-green); + box-shadow: 0 10px 26px rgba(0,0,0,.6), 0 0 14px rgba(57,255,20,.22); +} + +/* Botones del header (compatibles) */ +.nav-menu button{ + composes: btn; + /* composes no es estándar; replicamos estilos: */ + --h: clamp(42px, 5.2vh, 54px); + --px: clamp(14px, 2.2vw, 22px); + font-family: var(--font-display); + font-weight: 800; + font-size: clamp(1.02rem, 1.5vw, 1.28rem); + height: var(--h); + padding: 0 var(--px); + border-radius: 12px; + border: 1px solid #1a1a1a; + background-image: var(--grad-gn-or); + background-size: 220% 100%; + background-position: 0% 50%; + color: #0b0b0b; + box-shadow: 0 6px 18px rgba(0,0,0,.55); + transition: background-position .35s ease, transform .12s ease, box-shadow .25s ease, filter .2s ease, border-color .2s ease; +} +.nav-menu button:hover{ + background-position: 100% 50%; transform: translateY(-1px); + box-shadow: 0 10px 26px rgba(0,0,0,.6), 0 0 18px rgba(57,255,20,.28), 0 0 28px rgba(255,122,24,.22); + border-color: #262626; filter: saturate(1.06); +} +.nav-menu button:active{ transform: translateY(0); box-shadow: inset 0 4px 10px rgba(0,0,0,.45); } +.nav-menu button:focus-visible{ outline: 2px solid rgba(57,255,20,.9); outline-offset: 3px; } +.nav-menu button.active{ + background: var(--neon-green); + color: #0b0b0b; + border-color: #2b2b2b; + box-shadow: 0 8px 22px rgba(0,0,0,.5), 0 0 10px rgba(57,255,20,.35); +} + +/* 5) Layout de la página About (full width real) */ +.about-page{ + /* sin caja centrada; usamos ancho completo para “llamar” */ + padding: 0; + overflow-y: auto; + min-height: 0; +} +.doc-card{ + width: 100%; + background: + radial-gradient(1400px 700px at 0% 0%, rgba(57,255,20,.06), transparent 60%), + linear-gradient(180deg, #121212 0%, #0e0e0e 100%); + border-top: 1px solid #171717; + border-bottom: 1px solid #171717; + /* borde redondeado opcional: */ + border-radius: 0; + box-shadow: 0 10px 28px var(--shadow) inset; + padding: clamp(18px, 3.2vw, 42px); + display: grid; + gap: clamp(16px, 2.2vw, 28px); +} + +/* 6) HERO / INTRO */ +.hero-head{ + display: grid; gap: clamp(10px, 1.4vw, 16px); + padding: clamp(8px, 1.2vw, 12px) 0 clamp(8px, 1.2vw, 12px); + border-bottom: 1px solid #202020; +} +.hero-title{ + font-family: var(--font-title); + font-size: clamp(2.2rem, 5.8vw, 4rem); + line-height: 1.05; + letter-spacing: .02em; + color: var(--neon-orange); + text-shadow: 0 0 8px rgba(255,122,24,.18); +} +.hero-title span{ color: var(--neon-green); text-shadow: 0 0 10px rgba(57,255,20,.22); } +.hero-subtitle{ + font-size: clamp(1.04rem, 1.8vw, 1.24rem); + color: var(--text); + max-width: 1100px; +} +.btn-row{ + display: flex; flex-wrap: wrap; gap: .75rem .85rem; + margin-top: .2rem; +} +.pills{ + display: flex; flex-wrap: wrap; gap: .5rem .6rem; list-style: none; +} +.pill{ + padding: .5rem .7rem; + border: 1px solid #242424; + border-radius: 999px; + background: #141414; + font-weight: 700; + font-size: .95rem; + color: #cfcfcf; +} + +/* 7) Bloques + tarjetas */ +.block{ display: grid; gap: .8rem; } +.block-title{ + font-family: var(--font-display); + font-size: clamp(1.3rem, 2.6vw, 1.7rem); + letter-spacing: .01em; +} +.grid-2{ + display: grid; gap: clamp(12px, 2vw, 18px); + grid-template-columns: repeat(2, minmax(0, 1fr)); +} +.card{ + background: var(--panel); + border: 1px solid var(--stroke); + border-radius: var(--radius); + box-shadow: 0 10px 26px var(--shadow); + padding: var(--pad); + display: grid; gap: .7rem; +} +.card h4{ + font-weight: 800; + font-size: clamp(1.05rem, 1.9vw, 1.25rem); + letter-spacing: .01em; +} + +/* 8) Listas */ +.check-list{ + display: grid; gap: .5rem; list-style: none; +} +.check-list li{ + position: relative; padding-left: 1.65rem; +} +.check-list li::before{ + content: "✓"; + position: absolute; left: 0; top: 0; + color: var(--neon-green); font-weight: 900; +} + +.dash-list{ + display: grid; gap: .45rem; list-style: none; +} +.dash-list li{ + position: relative; padding-left: 1.2rem; +} +.dash-list li::before{ + content: "—"; + position: absolute; left: 0; top: 0; color: #7c7c7c; +} + +.steps{ + display: grid; gap: .45rem; counter-reset: step; +} +.steps li{ + counter-increment: step; + position: relative; + padding-left: 2rem; +} +.steps li::before{ + content: counter(step); + position: absolute; left: 0; top: 0; + width: 1.4rem; height: 1.4rem; border-radius: 6px; + background: var(--neon-green); color: #0b0b0b; font-weight: 900; + display: inline-grid; place-items: center; +} + +/* 9) Índice rápido (fila de botones) */ +.index-row{ + display: flex; flex-wrap: wrap; gap: .6rem .7rem; + padding: .25rem 0 .2rem; + border-top: 1px solid #202020; + border-bottom: 1px solid #202020; +} + +/* 10) FAQ */ +.faq{ + background: #141414; + border: 1px solid #2a2a2a; + border-radius: 12px; + padding: .8rem 1rem; +} +.faq + .faq{ margin-top: .6rem; } +.faq summary{ cursor: pointer; list-style: none; } +.faq summary::-webkit-details-marker{ display: none; } +.faq summary::after{ content: "+"; float: right; font-weight: 900; } +.faq[open] summary::after{ content: "−"; } + +/* 11) Tipografía de texto general en secciones */ +.doc-card p, .doc-card ul, .doc-card ol{ + line-height: 1.7; + color: var(--text); +} + +/* 12) Responsive */ +@media (max-width: 1200px){ + .grid-2{ grid-template-columns: 1fr 1fr; } +} +@media (max-width: 900px){ + .site-title{ font-size: clamp(2.1rem, 7vw, 3.2rem); } + .nav-menu{ gap: .55rem .6rem; } + .nav-menu button{ height: clamp(40px, 5.2vh, 50px); font-size: 1rem; } + + .grid-2{ grid-template-columns: 1fr; } +} +@media (max-width: 680px){ + .btn{ --h: 44px; } + .btn-row{ gap: .6rem; } + .pill{ font-size: .9rem; } +} +@media (max-width: 480px){ + .hero-title{ font-size: clamp(1.8rem, 10vw, 2.3rem); } + .hero-subtitle{ font-size: 1rem; } +} diff --git a/3dcomunity/sub/about.html b/3dcomunity/sub/about.html index e69de29..2526f12 100644 --- a/3dcomunity/sub/about.html +++ b/3dcomunity/sub/about.html @@ -0,0 +1,185 @@ + + + + + + About — 3DCOMMUNITY.NET + + + + + + + +
+
+ + +
+

¿Qué es 3DCOMMUNITY.NET?

+

+ Un portal abierto para descargar y visualizar modelos + .stl (y más formatos 3D) listos para imprimir. Defendemos el + software libre, el conocimiento compartido y la cultura maker. +

+ + + + + +
    +
  • STL / OBJ / GLB
  • +
  • Modelos curados
  • +
  • Open Source ♥
  • +
  • Comunidad maker
  • +
+
+ + +
+

¿Qué encontrarás aquí?

+
+
+

Modelos listos para imprimir

+

+ Miniaturas, utilidades, piezas técnicas y prototipos. Cada entrada incluye + previsualización, notas de impresión (layer height, relleno, soportes) y enlaces. +

+ +
+
+

Tutoriales y buenas prácticas

+

+ Guías de calibración, perfiles para slicers, materiales y seguridad. + Recomendaciones para FDM y resina, y trucos para evitar warping. +

+ +
+
+
+ + + + + +
+

Valores y licencias

+

+ 3DCOMMUNITY.NET apoya el software libre, la + documentación abierta y los modelos con licencias claras. + Siempre que sea posible promovemos Creative Commons (p.ej. CC BY-SA) + y respetamos la atribución a autoras/es. +

+
    +
  • Preferimos licencias abiertas: CC BY, CC BY-SA, CERN-OHL, GPL…
  • +
  • Indicamos la autoría y los términos de uso cuando se aportan.
  • +
  • Fomentamos la remixabilidad y el aprendizaje colectivo.
  • +
+ +
+ + +
+

Cómo contribuir

+
    +
  1. Comparte tu STL/GLB y la información de impresión.
  2. +
  3. Indica la licencia y la autoría claramente.
  4. +
  5. Abre una propuesta en Code o manda el material por los canales indicados.
  6. +
  7. Participa en la moderación y curación de modelos.
  8. +
+ +
+ + +
+

Oasis / SSB: nuestra infraestructura distribuida

+

+ La parte social y de replicación se apoya en Oasis, basado en + Secure Scuttlebutt (SSB). Es decir, una red distribuida y + resiliente: cada persona mantiene su “diario” firmado y los mensajes + se replican entre pares y PUBs. +

+
+
+

Conceptos clave

+
    +
  • Identidad: par de claves ed25519, todo mensaje va firmado.
  • +
  • Append-only: historial inmutable, verificable.
  • +
  • Gossip: propagación entre nodos amigos.
  • +
  • PUBs: nodos de Internet que facilitan descubrimiento/replicación.
  • +
  • Offline-first: publica sin conexión y replica al volver.
  • +
+
+
+

Arquitectura del sitio

+
    +
  • Web: Nginx (HTTPS) → contenido estático (HTML+CSS).
  • +
  • Visor 3D: GLB con <model-viewer> (si hay JS).
  • +
  • Gossip SSB: puerto TCP 7724 hacia el contenedor PUB.
  • +
  • Certificados: Let’s Encrypt en el frontal.
  • +
+ +
+
+
+ + +
+

Preguntas rápidas (FAQ)

+ +
+ ¿Qué pasa si un PUB cae? +

La red sigue viva: tus pares conservan copias. Un PUB ayuda, pero no es un punto único de fallo.

+
+ +
+ ¿Puedo usar solo HTML/CSS? +

Sí. Con JS activamos visor GLB; sin JS mostramos previews e incluso enlaces directos a descarga.

+
+ +
+ ¿Cómo pido invitación a un PUB? +

Contacta con la administración del PUB para generar y validar la invitación.

+
+ + +
+ +
+
+ + diff --git a/3dcomunity/sub/code.css b/3dcomunity/sub/code.css new file mode 100644 index 0000000..7bf8c0e --- /dev/null +++ b/3dcomunity/sub/code.css @@ -0,0 +1,461 @@ +/* =========================== + code.css — 3DCOMUNITY.NET + Tema oscuro + verde neón / naranja + (rutas ABSOLUTAS para fuentes e imágenes) +=========================== */ + +/* 0) Reset + Variables */ +* { margin: 0; padding: 0; box-sizing: border-box; } +html, body { height: 100%; } + +:root{ + /* Colores base */ + --bg-0: #0a0a0a; + --bg-1: #0f0f0f; + --bg-2: #151515; + --panel: #1b1b1b; + --text: #f2f2f2; + --muted: #a9a9a9; + + /* Neón */ + --neon-green: #39FF14; + --neon-orange: #FF7A18; + + /* Gradientes */ + --grad-gn-or: linear-gradient(90deg, var(--neon-green) 0%, var(--neon-orange) 100%); + --grad-or-gn: linear-gradient(90deg, var(--neon-orange) 0%, var(--neon-green) 100%); + + /* Sombras / bordes */ + --shadow: rgba(0,0,0,.6); + --stroke: #0e0e0e; + + /* Tipografías */ + --font-ui: 'Oxanium', 'Rajdhani', 'Inter', system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; + --font-title: 'ThreeDIsometric', var(--font-ui); + --font-display: 'Gunplay', var(--font-ui); + --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; + + /* Tamaños */ + --header-h: clamp(88px, 16vh, 160px); + --radius: 16px; + --pad: clamp(14px, 2vw, 24px); +} + +/* 1) Fuentes locales (rutas ABSOLUTAS) */ +@font-face{ + font-family: 'ThreeDIsometric'; + src: url('/fonts/3DIsometric-Regular.ttf') format('truetype'), + url('/fonts/3DIsometric-Regular.otf') format('opentype'); + font-weight: 700; + font-style: normal; + font-display: swap; +} +@font-face{ + font-family: 'Gunplay'; + src: url('/fonts/Gunplay-Regular.otf') format('opentype'); + font-weight: 400; + font-style: normal; + font-display: swap; +} +@font-face{ + font-family: 'Oxanium'; + src: url('/fonts/Oxanium-VariableFont_wght.ttf') format('truetype'); + font-weight: 200 800; + font-style: normal; + font-display: swap; +} + +/* 2) Base documento */ +body{ + font-family: var(--font-ui); + color: var(--text); + background: + radial-gradient(1200px 700px at 8% -10%, #141414 0%, #0c0c0c 55%, #070707 100%), + var(--bg-0); + min-height: 100svh; + display: grid; + grid-template-rows: var(--header-h) 1fr; +} +*::-webkit-scrollbar { width: 10px; height: 10px; } +*::-webkit-scrollbar-thumb { background: #2a2a2a; border-radius: 999px; } +*::-webkit-scrollbar-thumb:hover { background: #3a3a3a; } + +@media (prefers-reduced-motion: reduce){ + * { animation: none !important; transition: none !important; } +} + +/* 3) Header + Navegación (coherente con about) */ +.site-header{ + background: linear-gradient(180deg, #0e0e0e 0%, #0a0a0a 100%); + border-bottom: 1px solid #121212; + box-shadow: 0 6px 24px var(--shadow); + display: grid; + grid-template-columns: auto 1fr auto; + align-items: center; + gap: .8rem; + padding: clamp(10px, 2vw, 18px) clamp(14px, 2.4vw, 22px); +} +.site-logo{ + display: inline-flex; align-items: center; justify-content: center; + width: 150px; height: 150px; border-radius: 12px; + background: #0f0f0f; border: 1px solid #222; + box-shadow: 0 8px 20px rgba(0,0,0,.5), 0 0 10px rgba(57,255,20,.15); + overflow: hidden; +} +.site-logo img{ display:block; width:100%; height:100%; object-fit: cover; } + +/* Variante opcional para logo grande (aplícale esta clase al contenedor del logo si lo quieres a 150x150) */ +.site-logo--150{ width:150px; height:150px; } + +/* Utilidad de imagen 150x150 (para cualquier imagen suelta) */ +.img-150{ width:150px; height:150px; object-fit:cover; border-radius:12px; display:block; } + +.site-title{ + justify-self: center; + font-family: var(--font-title); + font-weight: 800; + font-size: clamp(2.2rem, 5.8vw, 4.6rem); + letter-spacing: .06em; + color: var(--neon-orange); + text-shadow: + 0 0 6px rgba(255,122,24,.25), + 0 12px 28px rgba(0,0,0,.45); + white-space: nowrap; + /* más espacio con el bloque siguiente */ + margin-bottom: clamp(8px, 1.2vw, 16px); +} + +.nav-menu{ + display: flex; flex-wrap: wrap; justify-content: flex-end; + gap: .6rem .7rem; +} + +/* Botones del header */ +.nav-menu button{ + --h: clamp(42px, 5.2vh, 54px); + --px: clamp(14px, 2.2vw, 22px); + display: inline-flex; align-items: center; justify-content: center; + height: var(--h); padding: 0 var(--px); + border-radius: 12px; + border: 1px solid #1a1a1a; + font-family: var(--font-display); + font-weight: 800; + font-size: clamp(1.02rem, 1.5vw, 1.22rem); + letter-spacing: .02em; + background-image: var(--grad-gn-or); + background-size: 220% 100%; + background-position: 0% 50%; + color: #0b0b0b; + box-shadow: 0 6px 18px rgba(0,0,0,.55); + transition: background-position .35s ease, transform .12s ease, box-shadow .25s ease, filter .2s ease, border-color .2s ease, opacity .2s ease; + cursor: pointer; +} +.nav-menu button:hover{ + background-position: 100% 50%; transform: translateY(-1px); + box-shadow: 0 10px 26px rgba(0,0,0,.6), 0 0 18px rgba(57,255,20,.28), 0 0 28px rgba(255,122,24,.22); + border-color: #262626; filter: saturate(1.06); +} +.nav-menu button:active{ transform: translateY(0); box-shadow: inset 0 4px 10px rgba(0,0,0,.45); } +.nav-menu button:focus-visible{ outline: 2px solid rgba(57,255,20,.9); outline-offset: 3px; } +.nav-menu button.active{ + background: var(--neon-green); + color: #0b0b0b; + border-color: #2b2b2b; + box-shadow: 0 8px 22px rgba(0,0,0,.5), 0 0 10px rgba(57,255,20,.35); +} + +/* 4) Botones globales (CTA dentro del contenido) */ +.btn{ + --h: clamp(44px, 5.4vh, 56px); + --px: clamp(16px, 2.4vw, 26px); + + display: inline-flex; align-items: center; justify-content: center; + height: var(--h); padding: 0 var(--px); + border-radius: 14px; + border: 1px solid #1a1a1a; + font-family: var(--font-display); + font-weight: 800; letter-spacing: .02em; + text-decoration: none; user-select: none; cursor: pointer; + + background-image: var(--grad-gn-or); + background-size: 220% 100%; + background-position: 0% 50%; + color: #0b0b0b; + + box-shadow: + 0 8px 22px rgba(0,0,0,.55), + 0 0 0 0 rgba(57,255,20,0); + transition: background-position .35s ease, transform .12s ease, + box-shadow .25s ease, filter .2s ease, border-color .2s ease, opacity .2s ease; + position: relative; isolation: isolate; +} +.btn::after{ + content:""; position: absolute; inset: -2px; border-radius: inherit; + background: radial-gradient(60% 60% at 50% 50%, rgba(57,255,20,.18), rgba(255,122,24,.1) 60%, transparent 70%); + z-index: -1; opacity: 0; transition: opacity .25s ease; +} +.btn:hover{ + background-position: 100% 50%; + transform: translateY(-1px); + box-shadow: + 0 14px 28px rgba(0,0,0,.65), + 0 0 18px rgba(57,255,20,.28), + 0 0 28px rgba(255,122,24,.22); + filter: saturate(1.07); + border-color: #262626; +} +.btn:hover::after{ opacity: 1; } +.btn:active{ transform: translateY(0); box-shadow: inset 0 4px 10px rgba(0,0,0,.45); } +.btn:focus-visible{ outline: 2px solid rgba(57,255,20,.9); outline-offset: 3px; } + +/* Variantes */ +.btn-green{ background-image: none; background: var(--neon-green); } +.btn-orange{ background-image: none; background: var(--neon-orange); } +.btn-outline{ + background: transparent; + color: var(--text); + border-color: #2d2d2d; + box-shadow: 0 8px 22px rgba(0,0,0,.45); +} +.btn-outline:hover{ + background: #151515; + border-color: var(--neon-green); + box-shadow: 0 10px 26px rgba(0,0,0,.6), 0 0 14px rgba(57,255,20,.22); +} + +/* 5) Layout de la página Code */ +.code-page{ + padding: 0; + overflow-y: auto; + min-height: 0; +} +.doc-card{ + width: 100%; + background: + radial-gradient(1400px 700px at 0% 0%, rgba(57,255,20,.06), transparent 60%), + linear-gradient(180deg, #121212 0%, #0e0e0e 100%); + border-top: 1px solid #171717; + border-bottom: 1px solid #171717; + border-radius: 0; + box-shadow: 0 10px 28px var(--shadow) inset; + padding: clamp(18px, 3.2vw, 42px); + display: grid; + gap: clamp(18px, 2.6vw, 32px); /* un poco más de espacio general */ +} + +/* HERO / INTRO: más espacio con el título */ +.hero-head{ + display: grid; gap: clamp(12px, 1.6vw, 18px); + padding: clamp(10px, 1.4vw, 14px) 0 clamp(14px, 2vw, 20px); + border-bottom: 1px solid #202020; + margin-bottom: clamp(12px, 2vw, 22px); +} +.hero-title{ + font-family: var(--font-title); + font-size: clamp(2.2rem, 5.8vw, 4rem); + line-height: 1.05; + letter-spacing: .02em; + color: var(--neon-orange); + text-shadow: 0 0 8px rgba(255,122,24,.18); + margin-bottom: clamp(10px, 1.6vw, 18px); /* más separación bajo el título */ +} +.hero-title span{ color: var(--neon-green); text-shadow: 0 0 10px rgba(57,255,20,.22); } +.hero-subtitle{ + font-size: clamp(1.02rem, 1.7vw, 1.2rem); + color: var(--text); + max-width: 1100px; +} +.btn-row{ + display: flex; flex-wrap: wrap; gap: .75rem .85rem; + margin-top: .2rem; +} +.pills{ + display: flex; flex-wrap: wrap; gap: .5rem .6rem; list-style: none; +} +.pill{ + padding: .5rem .7rem; + border: 1px solid #242424; + border-radius: 999px; + background: #141414; + font-weight: 700; + font-size: .95rem; + color: #cfcfcf; +} + +/* 6) Índice rápido (fila de botones) */ +.index-row{ + display: flex; flex-wrap: wrap; gap: .6rem .7rem; + padding: .25rem 0 .2rem; + border-top: 1px solid #202020; + border-bottom: 1px solid #202020; +} + +/* 7) Bloques + tarjetas */ +.block{ display: grid; gap: .9rem; } +.block-title{ + font-family: var(--font-display); + font-size: clamp(1.28rem, 2.4vw, 1.7rem); + letter-spacing: .01em; + margin-bottom: .25rem; /* aire extra antes del contenido del bloque */ +} +.grid-2{ + display: grid; gap: clamp(14px, 2.2vw, 20px); + grid-template-columns: repeat(2, minmax(0, 1fr)); +} +.card{ + background: var(--panel); + border: 1px solid var(--stroke); + border-radius: var(--radius); + box-shadow: 0 10px 26px var(--shadow); + padding: var(--pad); + display: grid; gap: .7rem; +} +.card h4{ + font-weight: 800; + font-size: clamp(1.05rem, 1.9vw, 1.25rem); + letter-spacing: .01em; +} +.doc-card p, .doc-card ul, .doc-card ol{ + line-height: 1.7; + color: var(--text); +} + +/* 8) ASCII y bloques de código */ +.ascii{ + font-family: var(--font-mono); + font-size: clamp(.86rem, 1.2vw, .98rem); + line-height: 1.35; + background: #0f0f0f; + color: #d7d7d7; + border: 1px solid #242424; + border-left-width: 6px; + border-radius: 10px; + padding: 1rem 1.1rem; + box-shadow: inset 0 0 0 1px rgba(255,255,255,.02), 0 12px 28px rgba(0,0,0,.55); + overflow: auto; +} +.ascii.gn{ border-left-color: var(--neon-green); } +.ascii.or{ border-left-color: var(--neon-orange); } + +.code{ + font-family: var(--font-mono); + background: #101010; + color: #eaeaea; + border: 1px solid #262626; + border-radius: 12px; + padding: .9rem 1rem; + overflow: auto; + box-shadow: inset 0 0 0 1px rgba(255,255,255,.02), 0 10px 24px rgba(0,0,0,.5); +} + +/* 9) Demo visor 3D */ +.demo-3d{ + background: #0b0b0b; + border: 1px solid #1f1f1f; + border-radius: 14px; + box-shadow: + 0 10px 26px rgba(0,0,0,.6), + 0 0 18px rgba(57,255,20,.10), + inset 0 0 0 1px rgba(255,255,255,.02); + padding: 10px; +} +model-viewer{ + display: block; + width: 100%; + height: clamp(320px, 48vh, 540px); + background: #000; + border-radius: 10px; + outline: 1px solid #111; +} + +/* 10) Listas específicas */ +.check-list{ + display: grid; gap: .5rem; list-style: none; +} +.check-list li{ + position: relative; padding-left: 1.65rem; +} +.check-list li::before{ + content: "✔"; + position: absolute; left: 0; top: 0; + color: var(--neon-green); font-weight: 900; +} + +.dash-list{ + display: grid; gap: .45rem; list-style: none; +} +.dash-list li{ + position: relative; padding-left: 1.2rem; +} +.dash-list li::before{ + content: "—"; + position: absolute; left: 0; top: 0; color: #7c7c7c; +} + +/* 11) FAQ — Ajustes solicitados + - Más aire con el título global ya dado (hero-title/hero-head) + - Letra (cuerpo) de las preguntas un poco más pequeña + - Efecto “letra inicial” de dos líneas en el +*/ +.faq{ + background: #141414; + border: 1px solid #2a2a2a; + border-radius: 12px; + padding: .8rem 1rem; +} +.faq + .faq{ margin-top: .7rem; } + +.faq summary{ + cursor: pointer; list-style: none; + font-size: clamp(.96rem, 1.05vw, 1.06rem); /* ligeramente más pequeño */ + line-height: 1.55; /* más legible */ + letter-spacing: .01em; + position: relative; +} + +/* “Letra inicial” en dos líneas aprox (robusto cross-browser con ::first-letter) */ +.faq summary::first-letter{ + float: left; + font-family: var(--font-display); + font-weight: 800; + font-size: 2.2em; /* ~2 líneas según el tamaño final */ + line-height: .95; + margin-right: .38rem; + margin-top: .05rem; + color: var(--neon-green); + text-shadow: 0 0 8px rgba(57,255,20,.18); +} + +/* Marcador +/– */ +.faq summary::-webkit-details-marker{ display: none; } +.faq summary::after{ + content: "+"; + float: right; font-weight: 900; + color: var(--neon-orange); +} +.faq[open] summary::after{ content: "–"; } + +/* 12) Responsive */ +@media (max-width: 1200px){ + .grid-2{ grid-template-columns: 1fr 1fr; } +} +@media (max-width: 980px){ + .site-header{ grid-template-columns: 1fr; justify-items: center; row-gap: .6rem; } + .site-title{ order: 2; font-size: clamp(2.1rem, 7vw, 3.2rem); } + .nav-menu{ order: 3; justify-content: center; } + .site-logo{ order: 1; } +} +@media (max-width: 900px){ + .grid-2{ grid-template-columns: 1fr; } +} +@media (max-width: 680px){ + .btn{ --h: 44px; } + .btn-row{ gap: .6rem; } + .pill{ font-size: .9rem; } + /* Mantener el drop-cap legible en pantallas pequeñas */ + .faq summary::first-letter{ font-size: 2em; margin-right: .32rem; } +} +@media (max-width: 480px){ + .hero-title{ font-size: clamp(1.8rem, 10vw, 2.3rem); } + .hero-subtitle{ font-size: 1rem; } +} diff --git a/3dcomunity/sub/code.html b/3dcomunity/sub/code.html index 730955f..6d3a10a 100644 --- a/3dcomunity/sub/code.html +++ b/3dcomunity/sub/code.html @@ -1,35 +1,192 @@ - + - 3Dcomunity - - + Code — 3Dcomunity + + + + + + + +
+ +
+

Cómo movemos tus modelos: de STL a GLB, a la web y a Oasis

+

+ Resumen simple de nuestra cadena: limpiamos STL/OBJ, convertimos a GLB optimizado, generamos miniaturas, + servimos por web estática y anunciamos en el PUB Oasis para replicación. Todo ligero, auditable y resistente. +

+ +
    +
  • STL/OBJ → GLB
  • +
  • Thumbnails
  • +
  • Catálogo JSON
  • +
  • Nginx estático
  • +
  • Oasis / SSB
  • +
+
+ + + +
+

Pipeline básico (alto nivel)

+ +
+[1] Ingesta            [2] Limpieza           [3] Conversión          [4] Thumbs
+STL / OBJ / STEP  -->  escala/ejes/normales  -->  GLB optimizado  -->  JPG/WEBP 512px
+
+[5] Catálogo           [6] Web estática       [7] Anuncio Oasis
+JSON (metadatos)  -->  Nginx / CDN            -->  PUB: hash + URL/refs
+      
+ +
+
+

1) Ingesta & limpieza

+
    +
  • Validamos licencia y autoría.
  • +
  • Normalizamos unidades (mm) y ejes (Y-up → Z-up si procede).
  • +
  • Recalculamos normales, soldamos vértices duplicados.
  • +
+
+ +
+

2) Conversión a GLB

+

Usamos herramientas reproducibles (ej. Blender CLI / gltfpack) para un GLB ligero y web-friendly.

+
# Ejemplo (alto nivel)
+blender -b -P scripts/stl2glb.py -- --in model.stl --out model.glb
+gltfpack -i model.glb -o model.glb -cc -tc   # compresión + tangentes
+
+ +
+

3) Miniaturas

+
    +
  • Render rápido con cámara fija → /sub/thumbs/*.webp.
  • +
  • Nombres consistentes: nombre.glbnombre.webp.
  • +
+
+ +
+

4) Catálogo & publicación

+
    +
  • Metadatos en catalog.json (autor, tema, material, complejidad, tags).
  • +
  • Web estática servida por Nginx.
  • +
  • Mensaje en Oasis/SSB con hash de contenido y referencias públicas.
  • +
+
+
+
+ + +
+

Demo visor 3D — snh_base.glb

+

Previsualización rápida con <model-viewer>. Mueve, rota y haz zoom sin plugins.

+ +
+ + +
+ + +
+ + +
+

Topología mínima de despliegue

+
+Navegador ──HTTPS──► Nginx (RP)
+                        │
+                        ├──► / (estático: HTML/CSS/GLB/WEBP)
+                        └──► /app (si hay backend/API)
+
+Gossip (SSB) ──TCP/7724──► PUB Oasis
+      
+

La web es estática para rapidez y resiliencia. Oasis se usa para anunciar y replicar referencias de modelos/contenidos.

+
+ + +
+

Conceptos claros

+
    +
  • GLB: formato web binario (gltf) con mejor carga que STL/OBJ.
  • +
  • Offline-first: puedes navegar la web estática sin depender del PUB.
  • +
  • PUB Oasis: nodo público para descubrimiento/replicación (no SPOF).
  • +
  • Auditable: herramientas CLI, ficheros estáticos y hashes verificables.
  • +
+
+ + +
+

FAQ

+ +
+ ¿Por qué convertís a GLB? +

Porque reduce peso, empaqueta materiales y es el estándar de facto para la web (cargas rápidas y consistentes).

+
+ +
+ ¿Qué se replica exactamente en Oasis? +

Metadatos y referencias (hash/URL) de los modelos, para que otros nodos puedan descubrirlos/verificarlos.

+
+ +
+ ¿Se puede usar sin JavaScript? +

La web funciona; sin JS no verás el visor interactivo, pero podrás descargar GLB/WEBP desde la galería.

+
+
+ + +
+ +
- - - - - - - diff --git a/3dcomunity/sub/gallery.css b/3dcomunity/sub/gallery.css new file mode 100644 index 0000000..f90bb01 --- /dev/null +++ b/3dcomunity/sub/gallery.css @@ -0,0 +1,355 @@ +/* ========================================================= + /sub/gallery.css — 3DCOMMUNITY.NET + Tema neon (verde/naranja) + header/botones como about.css + (Fuentes absolutas para que funcionen desde /sub/) +========================================================= */ + +/* 0) Reset básico */ +* { box-sizing: border-box; margin: 0; padding: 0; } +html, body { height: 100%; } + +/* 1) Variables de tema */ +:root{ + /* Colores base */ + --bg-0: #0a0a0a; + --bg-1: #0f0f0f; + --bg-2: #151515; + --panel: #1b1b1b; + --text: #f2f2f2; + --muted: #a9a9a9; + + /* Neon */ + --neon-green: #39FF14; + --neon-orange: #FF7A18; + + /* Gradientes & sombras */ + --grad-gn-or: linear-gradient(90deg, var(--neon-green) 0%, var(--neon-orange) 100%); + --shadow: rgba(0,0,0,.6); + --stroke: #161616; + + /* Tipografías (coherentes con about.css) */ + --font-ui: 'Oxanium', 'Rajdhani', 'Inter', system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; + --font-title: 'ThreeDIsometric', var(--font-ui); + --font-display: 'Gunplay', var(--font-ui); + + /* Tamaños */ + --radius: 14px; + --gap: clamp(12px, 1.8vw, 20px); + --pad: clamp(12px, 2vw, 24px); +} + +/* 2) @font-face (rutas absolutas para que funcionen desde /sub) */ +@font-face{ + font-family: 'ThreeDIsometric'; + src: url('/fonts/3DIsometric-Regular.ttf') format('truetype'), + url('/fonts/3DIsometric-Regular.otf') format('opentype'); + font-weight: 700; font-style: normal; font-display: swap; +} +@font-face{ + font-family: 'Gunplay'; + src: url('/fonts/Gunplay-Regular.otf') format('opentype'); + font-weight: 400; font-style: normal; font-display: swap; +} +@font-face{ + font-family: 'Oxanium'; + src: url('/fonts/Oxanium-VariableFont_wght.ttf') format('truetype'); + font-weight: 200 800; font-style: normal; font-display: swap; +} + +/* 3) Base documento */ +body{ + font-family: var(--font-ui); + color: var(--text); + background: + radial-gradient(1400px 700px at 0% 0%, rgba(57,255,20,.06), transparent 60%), + linear-gradient(180deg, #121212 0%, #0e0e0e 100%); + min-height: 100svh; + display: grid; + grid-template-rows: auto 1fr; +} + +/* Scrollbar suave */ +*::-webkit-scrollbar { width: 10px; height: 10px; } +*::-webkit-scrollbar-thumb { background: #2a2a2a; border-radius: 999px; } +*::-webkit-scrollbar-thumb:hover { background: #3a3a3a; } + +/* 4) HEADER — mismo estilo que about.css */ +.site-header{ + background: linear-gradient(180deg, #0e0e0e 0%, #0a0a0a 100%); + border-bottom: 1px solid #121212; + box-shadow: 0 6px 24px var(--shadow); + display: grid; + grid-auto-rows: min-content; + align-content: center; + justify-items: center; + gap: .65rem; + padding: clamp(10px, 2vw, 18px) clamp(14px, 2.4vw, 22px) clamp(14px, 2.6vw, 28px); +} +.site-title{ + font-family: var(--font-title); + font-weight: 800; + font-size: clamp(2.6rem, 6.5vw, 5rem); + letter-spacing: .06em; + color: var(--neon-orange); + text-shadow: 0 0 6px rgba(255,122,24,.25), 0 12px 28px rgba(0,0,0,.45); + white-space: nowrap; +} +.nav-menu{ + display: flex; flex-wrap: wrap; justify-content: center; + gap: .75rem .85rem; +} +/* Botones del header (bonitos + hover) */ +.nav-menu button{ + --h: clamp(42px, 5.2vh, 54px); + --px: clamp(14px, 2.2vw, 22px); + + display: inline-flex; align-items: center; justify-content: center; + height: var(--h); padding: 0 var(--px); + border-radius: 12px; border: 1px solid #1a1a1a; + font-family: var(--font-display); + font-weight: 800; letter-spacing: .02em; + font-size: clamp(1.02rem, 1.5vw, 1.28rem); + cursor: pointer; + + background-image: var(--grad-gn-or); + background-size: 220% 100%; background-position: 0% 50%; + color: #0b0b0b; + + box-shadow: 0 6px 18px rgba(0,0,0,.55); + transition: background-position .35s ease, transform .12s ease, + box-shadow .25s ease, filter .2s ease, border-color .2s ease; +} +.nav-menu button:hover{ + background-position: 100% 50%; transform: translateY(-1px); + box-shadow: 0 10px 26px rgba(0,0,0,.6), + 0 0 18px rgba(57,255,20,.28), + 0 0 28px rgba(255,122,24,.22); + border-color: #262626; filter: saturate(1.06); +} +.nav-menu button:active{ transform: translateY(0); box-shadow: inset 0 4px 10px rgba(0,0,0,.45); } +.nav-menu button:focus-visible{ outline: 2px solid rgba(57,255,20,.9); outline-offset: 3px; } +.nav-menu button.active{ + background: var(--neon-green); + color: #0b0b0b; + border-color: #2b2b2b; + box-shadow: 0 8px 22px rgba(0,0,0,.5), 0 0 10px rgba(57,255,20,.35); +} + +/* 5) Utilidades */ +.state-anchor{ position: absolute; left: -9999px; width: 0; height: 0; overflow: hidden; } + +/* 6) Contenedor de página (full width real) */ +.gallery-page{ + width: 100%; + padding: var(--pad); + display: grid; gap: var(--gap); +} + +/* 7) Barra de búsqueda compacta (1 fila en desktop) */ +.gallery-bar{ + background: linear-gradient(180deg, #151515 0%, #111 100%); + border: 1px solid var(--stroke); + border-radius: 16px; + box-shadow: 0 8px 18px var(--shadow); + padding: clamp(10px, 1.6vw, 14px); + display: grid; gap: .6rem; +} +.gallery-bar form{ + display: grid; + grid-template-columns: 1fr repeat(4, minmax(140px, 220px)) auto; + gap: .6rem; align-items: center; +} +.gallery-bar input[type="search"], +.gallery-bar select{ + width: 100%; + padding: .65rem .7rem; + border-radius: 10px; + border: 2px solid #2a2a2a; + background: #151515; + color: var(--text); + transition: border-color .2s ease, box-shadow .2s ease, transform .08s ease; +} +.gallery-bar input::placeholder{ color:#8e8e8e; } +.gallery-bar input:hover, .gallery-bar select:hover{ + border-color: #333; box-shadow: 0 0 0 2px rgba(255,122,24,.12) inset; +} +.gallery-bar input:focus-visible, .gallery-bar select:focus-visible{ + outline: none; border-color: var(--neon-green); box-shadow: 0 0 0 3px rgba(57,255,20,.16); +} +.gallery-count{ color: var(--muted); } + +/* Botón genérico (coherente con about.css) */ +.btn{ + display:inline-flex; align-items:center; justify-content:center; + min-height: 44px; padding:.6rem 1rem; + border-radius: 10px; border: 1px solid #2a2a2a; + background: #191919; color: var(--text); + text-decoration: none; font-weight: 800; letter-spacing:.01em; font-family: var(--font-display); + transition: transform .12s ease, box-shadow .2s ease, border-color .2s ease, + background-position .35s ease, filter .2s ease; +} +.btn:hover{ transform: translateY(-1px); filter: saturate(1.05); } +.btn:focus-visible{ outline: 2px solid rgba(57,255,20,.9); outline-offset: 3px; } + +.btn-orange{ + background: var(--neon-orange); color:#111; border-color:#ff8a38; + box-shadow: 0 4px 10px rgba(0,0,0,.45), 0 0 10px rgba(255,122,24,.25); +} +.btn-orange:hover{ box-shadow: 0 8px 18px rgba(0,0,0,.55), 0 0 16px rgba(255,122,24,.35); } + +.btn-outline{ + background:#151515; color:var(--text); +} +.btn-outline:hover{ border-color: var(--neon-green); box-shadow: 0 0 0 3px rgba(57,255,20,.16); } + +.btn-green{ + color:#0b0b0b; border:none; + background-image: var(--grad-gn-or); + background-size: 220% 100%; background-position: 0% 50%; + box-shadow: 0 4px 12px rgba(0,0,0,.5); +} +.btn-green:hover{ + background-position: 100% 50%; + box-shadow: 0 8px 22px rgba(0,0,0,.55), + 0 0 12px rgba(57,255,20,.35), + 0 0 24px rgba(255,122,24,.25); +} + +/* 8) Rejilla 3→2→1 columnas */ +.gallery-grid.big{ + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: var(--gap); + align-content: start; +} + +/* 9) Tarjetas */ +.g-card{ + background:#141414; + border:1px solid #1f1f1f; + border-radius: var(--radius); + box-shadow: 0 8px 18px var(--shadow); + overflow: hidden; + display:grid; grid-template-rows:auto 1fr auto; + transition: transform .15s ease, box-shadow .2s ease, border-color .2s ease, filter .2s ease; +} +.g-card:hover{ + transform: translateY(-2px); + border-color: var(--neon-green); + box-shadow: + 0 12px 26px rgba(0,0,0,.6), + 0 0 14px rgba(57,255,20,.18), + 0 0 22px rgba(255,122,24,.18); + filter: saturate(1.06); +} +.g-link{ display:block; } +.g-thumb{ + width: 100%; + aspect-ratio: 16/10; + object-fit: cover; + background: + radial-gradient(60% 60% at 50% 45%, rgba(255,255,255,.04), transparent 60%), + linear-gradient(180deg, #0b0b0b, #0f0f0f); +} +/* Placeholder si falta imagen */ +.g-thumb[src=""], .g-thumb:not([src]){ + background: + linear-gradient(135deg, rgba(57,255,20,.08), rgba(255,122,24,.08)), + repeating-linear-gradient(45deg, #121212 0 10px, #141414 10px 20px); + border-bottom: 1px solid #1f1f1f; +} +.g-body{ + padding: clamp(12px, 1.6vw, 16px); + display:grid; gap:.35rem; color: var(--text); +} +.g-title{ font-weight: 800; letter-spacing: .01em; } +.g-meta{ font-size: .9rem; color: var(--muted); } +.g-actions{ + padding: clamp(12px, 1.6vw, 16px); + display:flex; gap:.5rem; justify-content:space-between; align-items:center; + border-top:1px solid #1e1e1e; +} + +/* 10) Overlay visor 3D (sin JS con :target) */ +.viewer-overlay{ + position: fixed; inset: 0; + background: + radial-gradient(1200px 700px at 8% -10%, rgba(57,255,20,.06), transparent 55%), + rgba(0,0,0,.86); + backdrop-filter: blur(2px); + display: none; z-index: 60; + padding: clamp(10px, 2vw, 20px); +} +.viewer-overlay:target{ display:block; } +/* al ir a #grid, se cierra */ +#grid:target ~ .viewer-overlay{ display:none; } + +.viewer-overlay .inner{ + max-width: 1280px; height: min(90vh, 860px); + margin: 0 auto; + background: #0b0b0b; + border: 1px solid #1f1f1f; + border-radius: 16px; + box-shadow: 0 12px 32px rgba(0,0,0,.65), 0 0 24px rgba(57,255,20,.08) inset; + display:grid; grid-template-rows:auto 1fr; overflow:hidden; +} +.viewer-overlay header{ + display:flex; align-items:center; justify-content:space-between; gap:.5rem; + padding:.75rem 1rem; + border-bottom:1px solid #1f1f1f; + background: linear-gradient(180deg, #121212, #0f0f0f); + color: var(--text); +} +.viewer-overlay .title{ font-weight: 800; letter-spacing: .02em; } +.viewer-overlay .close{ + text-decoration:none; padding:.45rem .8rem; border-radius:10px; + border:1px solid #2a2a2a; background:#151515; color:var(--text); + transition: border-color .2s ease, transform .08s ease, box-shadow .2s ease; +} +.viewer-overlay .close:hover{ + transform: translateY(-1px); + border-color: var(--neon-green); + box-shadow: 0 0 0 3px rgba(57,255,20,.14); +} +.viewer-overlay model-viewer{ width:100%; height:100%; background:#000; } +.nojs-msg{ padding:1rem; color:#ddd; } + +/* 11) Accesibilidad */ +.g-link:focus-visible, +.g-actions .btn:focus-visible, +.viewer-overlay .close:focus-visible{ + outline: 2px solid var(--neon-green); + outline-offset: 3px; +} + +/* 12) Responsive */ +@media (max-width:1100px){ + .gallery-bar form{ + grid-template-columns: 1fr repeat(3, minmax(140px, 1fr)) auto; + } + .gallery-grid.big{ + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} +@media (max-width:680px){ + .site-title{ font-size: clamp(2.1rem, 7vw, 3.2rem); } + .nav-menu{ gap: .55rem .6rem; } + .nav-menu button{ height: clamp(40px, 5.2vh, 50px); font-size: 1rem; } + + .gallery-bar form{ + grid-template-columns: 1fr 1fr; + grid-auto-rows: minmax(44px, auto); + } + .gallery-bar .btn{ grid-column: 1 / -1; } + .gallery-grid.big{ grid-template-columns: 1fr; } + + .viewer-overlay .inner{ + height: calc(100svh - 2 * clamp(10px, 2vw, 20px)); + max-width: 100%; + } +} + +/* Reduce motion */ +@media (prefers-reduced-motion: reduce){ + *{ animation: none !important; transition: none !important; } +} diff --git a/3dcomunity/sub/gallery.html b/3dcomunity/sub/gallery.html index a8b6a7b..f2792e5 100644 --- a/3dcomunity/sub/gallery.html +++ b/3dcomunity/sub/gallery.html @@ -1,11 +1,14 @@ - + - 3Dcomunity - - + Galería — 3Dcomunity + + + + + @@ -13,113 +16,437 @@ -
- - - - - - - - - - - - - - +
+ + - -
- - + + - - +
+ +
+
+
+
gaspiage
+ Cerrar +
+ + +
+
+ +
+
+
+
kraken
+ Cerrar +
+ + +
+
+ + +
+
+
davidchamorro
Cerrar
+ +
+
+ +
+
+
lobotomik
Cerrar
+ +
+
+ +
+
+
lockheart
Cerrar
+ +
+
+ +
+
+
mageb
Cerrar
+ +
+
+ +
+
+
mkellsy
Cerrar
+ +
+
+ +
+
+
prospect3dlab
Cerrar
+ +
+
+ +
+
+
snh_base
Cerrar
+ +
+
+ +
+
+
snh_usb_ether
Cerrar
+ +
+
+ +
+
+
tomasla
Cerrar
+ +
+
+ +
+
+
waseem-33
Cerrar
+ +
+
+ + + + + - - - - - - - diff --git a/3dcomunity/sub/styles.css b/3dcomunity/sub/styles.css new file mode 100644 index 0000000..935f585 --- /dev/null +++ b/3dcomunity/sub/styles.css @@ -0,0 +1,425 @@ +/* ================================= + 1) Fuentes + Variables + Reset +================================= */ + +/* Fuentes auto-hospedadas (en /home/web/3dcomunity/fonts) */ +@font-face{ + font-family: 'ThreeDIsometric'; + src: url('fonts/3DIsometric-Regular.ttf') format('truetype'), + url('fonts/3DIsometric-Regular.otf') format('opentype'); + font-weight: 400; + font-style: normal; + font-display: swap; +} +@font-face{ + font-family: 'ThreeDIsometric'; + src: url('fonts/3DIsometric-Bold.ttf') format('truetype'), + url('fonts/3DIsometric-Bold.otf') format('opentype'); + font-weight: 700; + font-style: normal; + font-display: swap; +} +@font-face{ + font-family: 'ThreeDIsometric'; + src: url('fonts/3DIsometric-Black.ttf') format('truetype'), + url('fonts/3DIsometric-Black.otf') format('opentype'); + font-weight: 800; + font-style: normal; + font-display: swap; +} +@font-face{ + font-family: 'Gunplay'; + src: url('fonts/Gunplay-Regular.otf') format('opentype'); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +/* Variables */ +:root { + --bg-dark: #0a0a0a; + --bg-panel: #1a1a1a; + --text-light: #f2f2f2; + --shadow: rgba(0,0,0,0.7); + + /* Neón */ + --neon-green: #39FF14; + --neon-orange: #FF7A18; + + /* Paleta para botones (gradiente) */ + --accent-green: var(--neon-green); + --accent-orange: var(--neon-orange); + --btn-grad: linear-gradient(90deg, var(--accent-green) 0%, var(--accent-orange) 100%); + + /* Hover/foco */ + --hover-green: #4caf50; + + /* Tipografías base */ + --font-sans: 'Rajdhani', sans-serif; + --font-title: 'ThreeDIsometric', var(--font-sans); + --font-buttons: 'Gunplay', var(--font-sans); +} + +* { margin:0; padding:0; box-sizing:border-box; } + +body { + font-family: var(--font-sans); + background: var(--bg-dark); + color: var(--text-light); + height: 100vh; + display: grid; + grid-template-rows: 15% 85%; +} + +/* ================================= + 2) Header + Menú +================================= */ + +/* --- Header: título arriba, botones debajo --- */ +.site-header{ + background:#111; + box-shadow:0 2px 6px var(--shadow); + display:grid; /* pila vertical: título + menú */ + grid-auto-rows:min-content; + justify-items:center; /* centra horizontalmente */ + align-content:center; /* centra verticalmente dentro del 15% */ + gap:.55rem; /* separación título/menú */ + padding:.6rem 1rem 1rem; + height:100%; +} + +/* Título solo color naranja (neón), tamaños sin cambios */ +.site-header .site-title{ + font-family: var(--font-title); + font-weight:800; + font-size: clamp(3rem, 5vw, 5rem); + letter-spacing:.06em; + line-height:1; + margin:0; + color: var(--neon-orange); + text-shadow: + 0 0 8px rgba(255,122,24,.25), + 0 8px 22px rgba(0,0,0,.35); + white-space: nowrap; +} + +/* Menú debajo del título, centrado */ +.nav-menu{ + height:auto; + display:flex; + flex-wrap:wrap; + justify-content:center; + gap:.8rem; +} + +/* Botones con gradiente verde→naranja */ +.nav-menu button{ + font-family: var(--font-buttons); + font-size: clamp(1.5rem, 1.2vw, 1.5rem); + padding:.85rem 1.2rem; + border:none; + border-radius:.65rem; + color:#0b0b0b; + cursor:pointer; + + background-image: var(--btn-grad); + background-size: 200% 100%; + background-position: 0% 50%; + box-shadow: + 0 4px 12px rgba(0,0,0,.5), + 0 0 0 0 rgba(57,255,20,0); + + transition: + background-position .35s ease, + transform .12s ease, + box-shadow .2s ease, + filter .2s ease; +} +.nav-menu button:hover { + background-position: 100% 50%; + transform: translateY(-1px); + box-shadow: + 0 8px 22px rgba(0,0,0,.55), + 0 0 12px rgba(57,255,20,.35), + 0 0 24px rgba(255,122,24,.25); + filter: saturate(1.05); +} +.nav-menu button:active { + transform: translateY(0); + box-shadow: 0 4px 10px rgba(0,0,0,.45) inset; +} +.nav-menu button:focus-visible { + outline: 2px solid rgba(57,255,20,.9); + outline-offset: 3px; + box-shadow: + 0 0 0 2px rgba(57,255,20,.35), + 0 0 10px rgba(255,122,24,.35); +} +.nav-menu button.active{ + /* estado activo en verde sólido */ + background: var(--accent-green); + background-image: none; + color:#0b0b0b; + box-shadow: + 0 6px 16px rgba(0,0,0,.5), + 0 0 10px rgba(57,255,20,.35); +} + +/* ================================= + 3) Layout principal +================================= */ + +.content { + display: flex; + height: 100%; +} + +/* Visor 3D (izquierda) */ +#viewer3d { + width: 70%; + background: #000; + padding: 0.5rem; + display: flex; + position: relative; +} + +/* Model-Viewer base (rellena el contenedor) */ +#viewer3d model-viewer { + width: 100%; + height: 100%; + border-radius: .6rem; + box-shadow: 0 6px 18px var(--shadow); + outline: 1px solid #111; +} + +/* ================================= + 4) Panel lateral +================================= */ + +.side-panel { + width: 30%; + background: var(--bg-panel); + padding: 1.5rem; + display: flex; + flex-direction: column; + gap: 1.5rem; + box-shadow: -4px 0 10px var(--shadow); +} + +/* ================================= + 5) Filtros desplegables +================================= */ + +.filters { + display: flex; + flex-direction: column; + gap: 1rem; +} +.filter label { + display: block; + margin-bottom: 0.3rem; + font-weight: bold; +} +.filter select { + width: 100%; + padding: 0.6rem; + border: 2px solid #444; + border-radius: 0.4rem; + background: #222; + color: var(--text-light); + cursor: pointer; + transition: border-color 0.2s ease, box-shadow 0.2s ease, transform .08s ease; +} +.filter select:hover { + border-color: var(--hover-green); + box-shadow: 0 0 5px rgba(76,175,80,0.6); + transform: translateY(-1px); +} + +/* ================================= + 6) Galería 3×3 (miniaturas) +================================= */ + +.gallery-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 0.8rem; + flex-grow: 1; + overflow-y: auto; +} +.gallery-item { + background: #222; + aspect-ratio: 1; + display: block; + border-radius: 0.3rem; + cursor: pointer; + border: 2px solid transparent; + overflow: hidden; + transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease, filter .2s ease; +} +.gallery-item:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px var(--shadow); + border-color: var(--hover-green); + filter: saturate(1.05); +} +.gallery-item img { + width: 100%; + height: 100%; + object-fit: cover; + display:block; + border-radius: .25rem; +} + +/* Placeholders (si aún no hay 9 imágenes) */ +.gallery-item.placeholder{ + color:#777; font-weight:700; font-size:1.2rem; + display:flex; align-items:center; justify-content:center; + background:#1f1f1f; +} + +/* ================================= + 7) Lógica sin JS (hash + :target) + - Anclas de estado invisibles + - Mostrar/ocultar según el hash + - Resaltar miniatura activa +================================= */ + +.state-anchor { + position:absolute; + left:-9999px; + width:0; height:0; + overflow:hidden; +} + +/* Por defecto: muestra solo el primer modelo (clase .default) */ +#viewer3d .mv { display: none; } +#viewer3d .mv.default { display: block; } + +/* Regla para cada estado (robot / benchy / cubo) */ +#m-robot:target ~ #viewer3d .mv { display: none; } +#m-robot:target ~ #viewer3d .mv[data-model="robot"] { display: block; } + +#m-benchy:target ~ #viewer3d .mv { display: none; } +#m-benchy:target ~ #viewer3d .mv[data-model="benchy"] { display: block; } + +#m-cubo:target ~ #viewer3d .mv { display: none; } +#m-cubo:target ~ #viewer3d .mv[data-model="cubo"] { display: block; } + +/* Resaltar miniatura activa según el :target */ +#m-robot:target ~ .side-panel .gallery-item[data-target="m-robot"], +#m-benchy:target ~ .side-panel .gallery-item[data-target="m-benchy"], +#m-cubo:target ~ .side-panel .gallery-item[data-target="m-cubo"] { + border-color: var(--hover-green); + box-shadow: 0 0 0 2px rgba(76,175,80,0.4) inset; +} + +/* ================================= + 8) Fallback sin JS para el visor (noscript) +================================= */ + +.nojs{ + background:#222; border:2px solid #444; border-radius:.5rem; + padding:1rem; margin-top:.5rem; text-align:center; +} +.nojs .btn{ + display:inline-block; margin-top:.6rem; padding:.6rem 1rem; + background: var(--btn-grad); + background-size: 200% 100%; + background-position: 0% 50%; + color:#111; border-radius:.4rem; text-decoration:none; font-weight:700; + box-shadow: 0 4px 8px var(--shadow); + transition: background-position .35s ease, transform .12s ease, box-shadow .2s ease; +} +.nojs .btn:hover{ + background-position: 100% 50%; + transform: translateY(-1px); + box-shadow: 0 8px 14px var(--shadow); +} +/* Mostrar/ocultar según el hash para cada modelo */ +#m-coolr3d24:target ~ #viewer3d .mv { display:none; } +#m-coolr3d24:target ~ #viewer3d .mv[data-model="coolr3d24"] { display:block; } + +#m-gaspiage:target ~ #viewer3d .mv { display:none; } +#m-gaspiage:target ~ #viewer3d .mv[data-model="gaspiage"] { display:block; } + +#m-kraken:target ~ #viewer3d .mv { display:none; } +#m-kraken:target ~ #viewer3d .mv[data-model="kraken"] { display:block; } + +#m-davidchamorro:target ~ #viewer3d .mv { display:none; } +#m-davidchamorro:target ~ #viewer3d .mv[data-model="davidchamorro"] { display:block; } + +#m-lobotomik:target ~ #viewer3d .mv { display:none; } +#m-lobotomik:target ~ #viewer3d .mv[data-model="lobotomik"] { display:block; } + +#m-lockheart:target ~ #viewer3d .mv { display:none; } +#m-lockheart:target ~ #viewer3d .mv[data-model="lockheart"] { display:block; } + +#m-mageb:target ~ #viewer3d .mv { display:none; } +#m-mageb:target ~ #viewer3d .mv[data-model="mageb"] { display:block; } + +#m-mkellsy:target ~ #viewer3d .mv { display:none; } +#m-mkellsy:target ~ #viewer3d .mv[data-model="mkellsy"] { display:block; } + +#m-prospect3dlab:target ~ #viewer3d .mv { display:none; } +#m-prospect3dlab:target ~ #viewer3d .mv[data-model="prospect3dlab"] { display:block; } + +#m-snh_base:target ~ #viewer3d .mv { display:none; } +#m-snh_base:target ~ #viewer3d .mv[data-model="snh_base"] { display:block; } + +#m-snh_usb_ether:target ~ #viewer3d .mv { display:none; } +#m-snh_usb_ether:target ~ #viewer3d .mv[data-model="snh_usb_ether"] { display:block; } + +#m-tomasla:target ~ #viewer3d .mv { display:none; } +#m-tomasla:target ~ #viewer3d .mv[data-model="tomasla"] { display:block; } + +#m-waseem-33:target ~ #viewer3d .mv { display:none; } +#m-waseem-33:target ~ #viewer3d .mv[data-model="waseem-33"] { display:block; } + +/* Resaltado de miniatura activa */ +#m-coolr3d24:target ~ .side-panel .gallery-item[data-target="m-coolr3d24"], +#m-gaspiage:target ~ .side-panel .gallery-item[data-target="m-gaspiage"], +#m-kraken:target ~ .side-panel .gallery-item[data-target="m-kraken"], +#m-davidchamorro:target ~ .side-panel .gallery-item[data-target="m-davidchamorro"], +#m-lobotomik:target ~ .side-panel .gallery-item[data-target="m-lobotomik"], +#m-lockheart:target ~ .side-panel .gallery-item[data-target="m-lockheart"], +#m-mageb:target ~ .side-panel .gallery-item[data-target="m-mageb"], +#m-mkellsy:target ~ .side-panel .gallery-item[data-target="m-mkellsy"], +#m-prospect3dlab:target ~ .side-panel .gallery-item[data-target="m-prospect3dlab"], +#m-snh_base:target ~ .side-panel .gallery-item[data-target="m-snh_base"], +#m-snh_usb_ether:target ~ .side-panel .gallery-item[data-target="m-snh_usb_ether"], +#m-tomasla:target ~ .side-panel .gallery-item[data-target="m-tomasla"], +#m-waseem-33:target ~ .side-panel .gallery-item[data-target="m-waseem-33"]{ + border-color: var(--hover-green); + box-shadow: 0 0 0 2px rgba(76,175,80,0.4) inset; +} + +/* ================================= + 9) Responsive +================================= */ + +@media (max-width: 900px){ + .site-header{ + padding: .5rem .75rem .85rem; + gap: .5rem; + } + /* mantenemos el tamaño del título con el clamp principal */ + .nav-menu{ gap: .6rem; } + .nav-menu button { padding: .75rem 1rem; font-size: 1.3rem; } +} + +@media (max-width: 680px){ + .site-header{ + padding: .5rem .75rem .75rem; + gap:.45rem; + } + .nav-menu{ + flex-wrap: wrap; + justify-content: center; + gap: .5rem .6rem; + } + .nav-menu button { font-size: 1.1rem; padding: .7rem .95rem; } + .content { flex-direction: column; } + #viewer3d { width: 100%; height: 60%; } + .side-panel { width: 100%; height: 40%; } +} diff --git a/3dcomunity/sub/tutorials.css b/3dcomunity/sub/tutorials.css new file mode 100644 index 0000000..d13b802 --- /dev/null +++ b/3dcomunity/sub/tutorials.css @@ -0,0 +1,246 @@ +/* ============================== + tutorials.css — 3Dcomunity + Tema neon (verde/naranja) + Full-width + responsive + (Coloca las fuentes en /fonts) +============================== */ + +/* 0) Reset + Vars */ +* { margin:0; padding:0; box-sizing:border-box; } +html, body { height:100%; } +:root{ + --bg-0:#0a0a0a; --bg-1:#0f0f0f; --bg-2:#151515; --panel:#1b1b1b; + --text:#f2f2f2; --muted:#a9a9a9; --stroke:#101010; --shadow:rgba(0,0,0,.55); + + --neon-green:#39FF14; --neon-orange:#FF7A18; + --grad-gn-or:linear-gradient(90deg,var(--neon-green),var(--neon-orange)); + + --font-ui:'Oxanium','Inter',system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif; + --font-title:'ThreeDIsometric',var(--font-ui); + --font-display:'Gunplay',var(--font-ui); + --mono: ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; + + --header-h:clamp(88px,16vh,150px); + --radius:16px; + --pad:clamp(14px,2vw,24px); +} + +/* 1) Fuentes locales (rutas absolutas para funcionar en /sub) */ +@font-face{ + font-family:'ThreeDIsometric'; + src:url('/fonts/3DIsometric-Regular.ttf') format('truetype'), + url('/fonts/3DIsometric-Regular.otf') format('opentype'); + font-weight:700; font-style:normal; font-display:swap; +} +@font-face{ + font-family:'Gunplay'; + src:url('/fonts/Gunplay-Regular.otf') format('opentype'); + font-weight:400; font-style:normal; font-display:swap; +} +@font-face{ + font-family:'Oxanium'; + src:url('/fonts/Oxanium-VariableFont_wght.ttf') format('truetype'); + font-weight:200 800; font-style:normal; font-display:swap; +} + +/* 2) Base documento */ +body{ + font-family:var(--font-ui); color:var(--text); + background: + radial-gradient(1200px 700px at 8% -10%,#141414 0%,#0c0c0c 55%,#070707 100%), + var(--bg-0); + min-height:100svh; + display:grid; grid-template-rows:var(--header-h) 1fr; +} +*::-webkit-scrollbar{ width:10px; height:10px; } +*::-webkit-scrollbar-thumb{ background:#2a2a2a; border-radius:999px; } +*::-webkit-scrollbar-thumb:hover{ background:#3a3a3a; } + +/* 3) Header + Navegación */ +.site-header{ + background:linear-gradient(180deg,#0e0e0e 0%,#0a0a0a 100%); + border-bottom:1px solid #121212; + box-shadow:0 6px 24px var(--shadow); + display:grid; + grid-template-columns:min-content 1fr auto; + align-items:center; + gap:clamp(8px,1.6vw,18px); + padding:clamp(10px,2vw,18px) clamp(14px,2.4vw,26px); +} +.site-logo{ display:inline-flex; align-items:center; } +.site-logo img{ + width:150px; height:150px; object-fit:contain; border-radius:10px; + box-shadow:0 0 0 1px #161616, 0 8px 18px rgba(0,0,0,.35); +} +.site-title{ + justify-self:center; text-align:center; + font-family:var(--font-title); font-weight:800; + font-size:clamp(2.4rem,6vw,4.4rem); + letter-spacing:.06em; color:var(--neon-orange); + text-shadow:0 0 6px rgba(255,122,24,.25),0 12px 28px rgba(0,0,0,.45); + white-space:nowrap; +} +.nav-menu{ display:flex; flex-wrap:wrap; justify-content:flex-end; gap:.7rem; } + +/* 4) Botones (global) */ +.btn{ + --h:clamp(44px,5.2vh,56px); --px:clamp(14px,2.2vw,24px); + display:inline-flex; align-items:center; justify-content:center; + height:var(--h); padding:0 var(--px); + border-radius:14px; border:1px solid #1a1a1a; + font-family:var(--font-display); font-weight:800; letter-spacing:.02em; + text-decoration:none; user-select:none; cursor:pointer; + background-image:var(--grad-gn-or); background-size:220% 100%; background-position:0% 50%; + color:#0b0b0b; + box-shadow:0 8px 22px rgba(0,0,0,.55); + transition:background-position .35s ease, transform .12s ease, box-shadow .25s ease, filter .2s ease, border-color .2s ease, opacity .2s ease; +} +.btn:hover{ + background-position:100% 50%; transform:translateY(-1px); + box-shadow:0 14px 28px rgba(0,0,0,.65), 0 0 18px rgba(57,255,20,.28), 0 0 28px rgba(255,122,24,.22); + filter:saturate(1.06); border-color:#262626; +} +.btn:active{ transform:translateY(0); box-shadow:inset 0 4px 10px rgba(0,0,0,.45); } +.btn:focus-visible{ outline:2px solid rgba(57,255,20,.9); outline-offset:3px; } + +.btn-green{ background:none; background-color:var(--neon-green); } +.btn-orange{ background:none; background-color:var(--neon-orange); } +.btn-outline{ + background:transparent; color:var(--text); border-color:#2d2d2d; + box-shadow:0 8px 22px rgba(0,0,0,.45); +} +.btn-outline:hover{ + background:#151515; border-color:var(--neon-green); + box-shadow:0 10px 26px rgba(0,0,0,.6),0 0 14px rgba(57,255,20,.22); +} + +/* Botones del header (usa .btn-like para - - - + + + + + +
+
+ +
+

Tutoriales 3Dcomunity

+

+ Guías claras para: STL → GLB, previsualizar con + <model-viewer> y publicar en Oasis/SSB. + Mantén los modelos ligeros, accesibles y fáciles de compartir. +

+ +
+ + + +
+

Inicio rápido (≈10 min)

+ +
+
+

1) Estructura mínima

+
.
+├─ index.html
+├─ /modelos
+│   └─ ejemplo.glb
+├─ /thumbs
+│   └─ ejemplo.jpg
+└─ /assets
+    └─ 3d_comunity_cool.webp
+
+
    +
  • Pon .glb en /modelos y miniaturas en /thumbs.
  • +
  • Usa rutas absolutas (/modelos/…) para evitar problemas en subdirectorios.
  • +
+
+ +
+

2) Visor web (<model-viewer>)

+
<script type="module"
+  src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js"></script>
+
+<model-viewer src="/modelos/ejemplo.glb"
+  camera-controls auto-rotate
+  shadow-intensity="1" exposure="1.05"
+  style="width:100%;height:420px;background:#000;border-radius:10px;">
+</model-viewer>
+
    +
  • Funciona en escritorio y móvil sin plugins.
  • +
  • Controla luz, auto-rotación y exposición.
  • +
+
+
+ + +
+ + +
+

Pipeline: de STL a GLB

+
+
+

Limpieza y reducción

+
    +
  • Importa el STL en Blender.
  • +
  • Repara normales y elimina vértices duplicados.
  • +
  • Aplica Decimate si pesa demasiado.
  • +
  • Materiales sencillos (PBR si procede).
  • +
+
+
+

Exportar a GLB

+
File → Export → glTF 2.0
+Format: GLB (binary)
+Include: Selected Objects (opcional)
+Compression: Draco (si compensa)
+Materials: Export
+
    +
  • GLB empaqueta geometría, materiales y texturas.
  • +
  • Si usas Draco, prueba en varios dispositivos.
  • +
+
+
+
+ + +
+

Visor 3D en la web

+
+

Snippet base

+
<model-viewer src="/modelos/ejemplo.glb"
+  camera-controls auto-rotate
+  ar ar-modes="webxr scene-viewer quick-look"
+  poster="/thumbs/ejemplo.jpg"
+  shadow-intensity="1" exposure="1.05">
+</model-viewer>
+
    +
  • Usa poster para una carga elegante.
  • +
  • Activa ar para móviles compatibles.
  • +
+
+
+ + +
+

Publicar en Oasis/SSB

+
+
+

Metadata simple

+
{
+  "name": "ejemplo",
+  "author": "taller3d",
+  "tags": ["utilidad","mini"],
+  "files": { "glb": "/modelos/ejemplo.glb",
+             "thumb": "/thumbs/ejemplo.jpg" }
+}
+
    +
  • Guárdalo como /modelos/ejemplo.json.
  • +
  • Te servirá para tarjetas y filtros.
  • +
+
+ +
+

Subir a tu PUB

+ +
    +
  • Sirve HTML+CSS+GLB vía Nginx.
  • +
  • El PUB facilita discovery y replicación.
  • +
+
+
+
+ + +
+

Despliegue estático (Nginx)

+
+

Ejemplo mínimo

+
server {
+  listen 443 ssl http2;
+  server_name 3dcomunity.net;
+
+  root /var/www/3dcomunity/public;
+  index index.html;
+
+  location / { try_files $uri $uri/ =404; }
+
+  types { model/gltf-binary glb; }
+}
+
    +
  • Asegura el MIME model/gltf-binary para .glb.
  • +
  • Rutas absolutas en tus HTML.
  • +
+
+
+ + +
+

FAQ

+ +
+ ¿Peso ideal de un GLB para móvil? +

Apunta a < 10 MB (ideal 2–5 MB). Simplifica malla y texturas.

+
+ +
+ ¿Usar STL directamente en navegador? +

Mejor no: STL suele pesar más y no trae materiales. Exporta a GLB.

+
+ +
+ ¿Cómo organizar muchos modelos? +

/modelos + /thumbs + /modelos/*.json (metadata) para filtrar y paginar.

+
+
+ + + + +
- - -